Signal-Android/app/src/main/protowire/Backup.proto

817 lines
21 KiB
Protocol Buffer
Raw Normal View History

syntax = "proto3";
package signal.backup;
option java_package = "org.thoughtcrime.securesms.backup.v2.proto";
message BackupInfo {
uint64 version = 1;
uint64 backupTimeMs = 2;
}
message Frame {
oneof item {
AccountData account = 1;
Recipient recipient = 2;
Chat chat = 3;
ChatItem chatItem = 4;
Call call = 5;
StickerPack stickerPack = 6;
}
}
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 noteToSelfMarkedUnread = 4;
bool linkPreviews = 5;
bool notDiscoverableByPhoneNumber = 6;
bool preferContactAvatars = 7;
uint32 universalExpireTimer = 8; // 0 means no universal expire timer.
repeated string preferredReactionEmoji = 9;
bool displayBadgesOnProfile = 10;
bool keepMutedChatsArchived = 11;
bool hasSetMyStoriesPrivacy = 12;
bool hasViewedOnboardingStory = 13;
bool storiesDisabled = 14;
optional bool storyViewReceiptsEnabled = 15;
bool hasSeenGroupStoryEducationSheet = 16;
bool hasCompletedUsernameOnboarding = 17;
PhoneNumberSharingMode phoneNumberSharingMode = 18;
}
bytes profileKey = 1;
optional string username = 2;
UsernameLink usernameLink = 3;
string givenName = 4;
string familyName = 5;
string avatarUrlPath = 6;
bytes subscriberId = 7;
string subscriberCurrencyCode = 8;
bool subscriptionManuallyCancelled = 9;
AccountSettings accountSettings = 10;
}
message Recipient {
uint64 id = 1; // generated id for reference only within this file
oneof destination {
Contact contact = 2;
Group group = 3;
DistributionList distributionList = 4;
Self self = 5;
ReleaseNotes releaseNotes = 6;
}
}
message Contact {
enum Registered {
UNKNOWN = 0;
REGISTERED = 1;
NOT_REGISTERED = 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;
bool hidden = 6;
Registered registered = 7;
uint64 unregisteredTimestamp = 8;
optional bytes profileKey = 9;
bool profileSharing = 10;
optional string profileGivenName = 11;
optional string profileFamilyName = 12;
bool hideStory = 13;
}
message Group {
enum StorySendMode {
DEFAULT = 0;
DISABLED = 1;
ENABLED = 2;
}
bytes masterKey = 1;
bool whitelisted = 2;
bool hideStory = 3;
StorySendMode storySendMode = 4;
}
message Self {}
message ReleaseNotes {}
message Chat {
uint64 id = 1; // generated id for reference only within this file
uint64 recipientId = 2;
bool archived = 3;
uint32 pinnedOrder = 4; // 0 = unpinned, otherwise chat is considered pinned and will be displayed in ascending order
uint64 expirationTimerMs = 5; // 0 = no expire timer.
uint64 muteUntilMs = 6;
bool markedUnread = 7;
bool dontNotifyForMentionsIfMuted = 8;
FilePointer wallpaper = 9;
}
message DistributionList {
enum PrivacyMode {
UNKNOWN = 0;
ONLY_WITH = 1;
ALL_EXCEPT = 2;
ALL = 3;
}
string name = 1;
bytes distributionId = 2; // distribution list ids are uuids
bool allowReplies = 3;
uint64 deletionTimestamp = 4;
PrivacyMode privacyMode = 5;
repeated uint64 memberRecipientIds = 6; // generated recipient id
}
message Identity {
bytes serviceId = 1;
bytes identityKey = 2;
uint64 timestamp = 3;
bool firstUse = 4;
bool verified = 5;
bool nonblockingApproval = 6;
}
message Call {
enum Type {
UNKNOWN_TYPE = 0;
AUDIO_CALL = 1;
VIDEO_CALL = 2;
GROUP_CALL = 3;
AD_HOC_CALL = 4;
}
enum Event {
UNKNOWN_EVENT = 0;
OUTGOING = 1; // 1:1 calls only
ACCEPTED = 2; // 1:1 and group calls. Group calls: You accepted a ring.
NOT_ACCEPTED = 3; // 1:1 calls only,
MISSED = 4; // 1:1 and group. Group calls: The remote ring has expired or was cancelled by the ringer.
DELETE = 5; // 1:1 and Group/Ad-Hoc Calls.
GENERIC_GROUP_CALL = 6; // Group/Ad-Hoc Calls only. Initial state
JOINED = 7; // Group Calls: User has joined the group call.
DECLINED = 8; // Group Calls: If you declined a ring.
OUTGOING_RING = 9; // Group Calls: If you are ringing a group.
}
uint64 callId = 1;
uint64 conversationRecipientId = 2;
Type type = 3;
bool outgoing = 4;
uint64 timestamp = 5;
optional uint64 ringerRecipientId = 6;
Event event = 7;
}
message ChatItem {
message IncomingMessageDetails {
uint64 dateReceived = 1;
uint64 dateServerSent = 2;
bool read = 3;
}
message OutgoingMessageDetails {
repeated SendStatus sendStatus = 1;
}
message DirectionlessMessageDetails {
}
uint64 chatId = 1; // conversation id
uint64 authorId = 2; // recipient id
uint64 dateSent = 3;
bool sealedSender = 4;
optional uint64 expireStartDate = 5; // timestamp of when expiration timer started ticking down
optional uint64 expiresInMs = 6; // how long timer of message is (ms)
repeated ChatItem revisions = 7; // ordered from oldest to newest
bool sms = 8;
oneof directionalDetails {
IncomingMessageDetails incoming = 9;
OutgoingMessageDetails outgoing = 10;
DirectionlessMessageDetails directionless = 11;
}
oneof item {
StandardMessage standardMessage = 13;
ContactMessage contactMessage = 14;
VoiceMessage voiceMessage = 15;
StickerMessage stickerMessage = 16;
RemoteDeletedMessage remoteDeletedMessage = 17;
ChatUpdateMessage updateMessage = 18;
}
}
message SendStatus {
enum Status {
UNKNOWN = 0;
FAILED = 1;
PENDING = 2;
SENT = 3;
DELIVERED = 4;
READ = 5;
VIEWED = 6;
SKIPPED = 7; // e.g. user in group was blocked, so we skipped sending to them
}
uint64 recipientId = 1;
Status deliveryStatus = 2;
bool networkFailure = 3;
bool identityKeyMismatch = 4;
bool sealedSender = 5;
uint64 lastStatusUpdateTimestamp = 6; // the time the status was last updated -- if from a receipt, it should be the sentTime of the receipt
}
message Text {
string body = 1;
repeated BodyRange bodyRanges = 2;
}
message StandardMessage {
optional Quote quote = 1;
optional Text text = 2;
repeated FilePointer attachments = 3;
repeated LinkPreview linkPreview = 4;
optional FilePointer longText = 5;
repeated Reaction reactions = 6;
}
message ContactMessage {
repeated ContactAttachment contact = 1;
repeated Reaction reactions = 2;
}
message ContactAttachment {
message Name {
optional string givenName = 1;
optional string familyName = 2;
optional string prefix = 3;
optional string suffix = 4;
optional string middleName = 5;
optional string displayName = 6;
}
message Phone {
enum Type {
UNKNOWN = 0;
HOME = 1;
MOBILE = 2;
WORK = 3;
CUSTOM = 4;
}
optional string value = 1;
optional Type type = 2;
optional string label = 3;
}
message Email {
enum Type {
UNKNOWN = 0;
HOME = 1;
MOBILE = 2;
WORK = 3;
CUSTOM = 4;
}
optional string value = 1;
optional Type type = 2;
optional string label = 3;
}
message PostalAddress {
enum Type {
UNKNOWN = 0;
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 {
FilePointer avatar = 1;
}
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 DocumentMessage {
Text text = 1;
FilePointer document = 2;
repeated Reaction reactions = 3;
}
message VoiceMessage {
optional Quote quote = 1;
FilePointer audio = 2;
repeated Reaction reactions = 3;
}
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;
}
message LinkPreview {
string url = 1;
optional string title = 2;
optional FilePointer image = 3;
optional string description = 4;
optional uint64 date = 5;
}
message FilePointer {
message BackupLocator {
string mediaName = 1;
uint32 cdnNumber = 2;
}
message AttachmentLocator {
string cdnKey = 1;
uint32 cdnNumber = 2;
uint64 uploadTimestamp = 3;
}
message LegacyAttachmentLocator {
fixed64 cdnId = 1;
}
// An attachment that was backed up without being downloaded.
// Its MediaName should be generated as “{sender_aci}_{cdn_attachment_key}”,
// but should eventually transition to a BackupLocator with mediaName
// being the content hash once it is downloaded.
message UndownloadedBackupLocator {
bytes senderAci = 1;
string cdnKey = 2;
uint32 cdnNumber = 3;
}
enum Flags {
VOICE_MESSAGE = 0;
BORDERLESS = 1;
GIF = 2;
}
oneof locator {
BackupLocator backupLocator = 1;
AttachmentLocator attachmentLocator= 2;
LegacyAttachmentLocator legacyAttachmentLocator = 3;
UndownloadedBackupLocator undownloadedBackupLocator = 4;
}
optional bytes key = 5;
optional string contentType = 6;
// Size of fullsize decrypted media blob in bytes.
// Can be ignored if unset/unavailable.
optional uint32 size = 7;
optional bytes incrementalMac = 8;
optional bytes incrementalMacChunkSize = 9;
optional string fileName = 10;
optional uint32 flags = 11;
optional uint32 width = 12;
optional uint32 height = 13;
optional string caption = 14;
optional string blurHash = 15;
}
message Quote {
enum Type {
UNKNOWN = 0;
NORMAL = 1;
GIFTBADGE = 2;
}
message QuotedAttachment {
optional string contentType = 1;
optional string fileName = 2;
optional FilePointer thumbnail = 3;
}
optional uint64 targetSentTimestamp = 1; // null if the target message could not be found at time of quote insert
uint64 authorId = 2;
optional string text = 3;
repeated QuotedAttachment attachments = 4;
repeated BodyRange bodyRanges = 5;
Type type = 6;
}
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;
optional uint64 receivedTimestamp = 4;
uint64 sortOrder = 5; // A higher sort order means that a reaction is more recent
}
message ChatUpdateMessage {
oneof update {
SimpleChatUpdate simpleUpdate = 1;
GroupChangeChatUpdate groupChange = 2;
ExpirationTimerChatUpdate expirationTimerChange = 3;
ProfileChangeChatUpdate profileChange = 4;
ThreadMergeChatUpdate threadMerge = 5;
SessionSwitchoverChatUpdate sessionSwitchover = 6;
CallChatUpdate callingMessage = 7;
}
}
message CallChatUpdate{
oneof call {
uint64 callId = 1; // maps to id of Call from call log
IndividualCallChatUpdate callMessage = 2;
GroupCallChatUpdate groupCall = 3;
}
}
message IndividualCallChatUpdate {
enum Type {
UNKNOWN = 0;
INCOMING_AUDIO_CALL = 1;
INCOMING_VIDEO_CALL = 2;
OUTGOING_AUDIO_CALL = 3;
OUTGOING_VIDEO_CALL = 4;
MISSED_AUDIO_CALL = 5;
MISSED_VIDEO_CALL = 6;
}
Type type = 1;
}
message GroupCallChatUpdate {
bytes startedCallAci = 1;
uint64 startedCallTimestamp = 2;
repeated bytes inCallAcis = 3;
}
message SimpleChatUpdate {
enum Type {
UNKNOWN = 0;
JOINED_SIGNAL = 1;
IDENTITY_UPDATE = 2;
IDENTITY_VERIFIED = 3;
IDENTITY_DEFAULT = 4; // marking as unverified
CHANGE_NUMBER = 5;
BOOST_REQUEST = 6;
END_SESSION = 7;
CHAT_SESSION_REFRESH = 8;
BAD_DECRYPT = 9;
PAYMENTS_ACTIVATED = 10;
PAYMENT_ACTIVATION_REQUEST = 11;
}
Type type = 1;
}
// For 1:1 chat updates only.
// For group thread updates use GroupExpirationTimerUpdate.
message ExpirationTimerChatUpdate {
uint32 expiresInMs = 1; // 0 means the expiration timer was disabled
}
message ProfileChangeChatUpdate {
string previousName = 1;
string newName = 2;
}
message ThreadMergeChatUpdate {
uint64 previousE164 = 1;
}
message SessionSwitchoverChatUpdate {
uint64 e164 = 1;
}
message GroupChangeChatUpdate {
message Update {
// Note: group expiration timer changes are represented as ExpirationTimerChatUpdate.
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 {
optional 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 {
int32 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 {
int32 droppedMembersCount = 1;
}
// For 1:1 timer updates, use ExpirationTimerChatUpdate.
message GroupExpirationTimerUpdate {
uint32 expiresInMs = 1; // 0 means the expiration timer was disabled
optional bytes updaterAci = 2;
}
message StickerPack {
bytes id = 1;
bytes key = 2;
string title = 3;
string author = 4;
repeated StickerPackSticker stickers = 5; // First one should be cover sticker.
}
message StickerPackSticker {
FilePointer data = 1;
string emoji = 2;
}