Files
Signal-iOS/SignalServiceKit/Protos/Specifications/StorageService.proto
2025-09-15 15:45:28 -05:00

287 lines
6.7 KiB
Protocol Buffer

//
// Copyright 2019 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
syntax = "proto3";
// iOS - package name determines class prefix
package StorageServiceProtos;
message StorageItem {
// @required
bytes key = 1; // Randomly generated 16-byte value
// @required
bytes value = 2; // Encrypted serialized bytes
}
message StorageItems {
repeated StorageItem items = 1; // Corresponds to the requested
// keys that were found
}
enum OptionalBool {
UNSET = 0;
TRUE = 1;
FALSE = 2;
}
message StorageManifest {
// @required
uint64 version = 1; // Monotonically increasing value
// @required
bytes value = 2; // Encrypted ManifestRecord bytes
}
message ReadOperation {
repeated bytes readKey = 1;
}
message WriteOperation {
StorageManifest manifest = 1;
repeated StorageItem insertItem = 2;
repeated bytes deleteKey = 3;
bool deleteAll = 4;
}
message ManifestRecord {
message Key {
enum Type {
UNKNOWN = 0;
CONTACT = 1;
GROUPV1 = 2;
GROUPV2 = 3;
ACCOUNT = 4;
STORY_DISTRIBUTION_LIST = 5;
CALL_LINK = 7;
}
// @required
bytes data = 1;
// @required
Type type = 2;
}
// @required
uint64 version = 1;
uint32 sourceDevice = 3;
repeated Key keys = 2;
bytes recordIkm = 4;
}
message StorageRecord {
oneof record {
ContactRecord contact = 1;
GroupV1Record groupV1 = 2;
GroupV2Record groupV2 = 3;
AccountRecord account = 4;
StoryDistributionListRecord storyDistributionList = 5;
CallLinkRecord callLink = 7;
}
}
// 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 ContactRecord {
enum IdentityState {
DEFAULT = 0;
VERIFIED = 1;
UNVERIFIED = 2;
}
message Name {
string given = 1;
string family = 2;
}
string aci = 1;
string e164 = 2;
string pni = 15;
bytes profileKey = 3;
bytes identityKey = 4;
IdentityState identityState = 5;
string givenName = 6;
string familyName = 7;
string username = 8;
bool blocked = 9;
bool whitelisted = 10;
bool archived = 11;
bool markedUnread = 12;
uint64 mutedUntilTimestamp = 13;
bool hideStory = 14;
uint64 unregisteredAtTimestamp = 16;
string systemGivenName = 17;
string systemFamilyName = 18;
string systemNickname = 19;
bool hidden = 20;
Name nickname = 22;
string note = 23;
optional AvatarColor avatarColor = 24;
}
message GroupV1Record {
// @required
bytes id = 1;
reserved /*blocked*/ 2;
reserved /*whitelisted*/ 3;
reserved /*archived*/ 4;
reserved /*markedUnread*/ 5;
reserved /*mutedUntilTimestamp*/ 6;
}
message GroupV2Record {
enum StorySendMode {
DEFAULT = 0;
DISABLED = 1;
ENABLED = 2;
}
// @required
bytes masterKey = 1;
bool blocked = 2;
bool whitelisted = 3;
bool archived = 4;
bool markedUnread = 5;
uint64 mutedUntilTimestamp = 6;
bool dontNotifyForMentionsIfMuted = 7;
bool hideStory = 8;
StorySendMode storySendMode = 10;
optional AvatarColor avatarColor = 11;
}
message AccountRecord {
enum PhoneNumberSharingMode {
UNKNOWN = 0;
EVERYBODY = 1;
NOBODY = 2;
}
message PinnedConversation {
message Contact {
string serviceId = 1;
string e164 = 2;
}
oneof identifier {
Contact contact = 1;
bytes legacyGroupId = 3;
bytes groupMasterKey = 4;
}
}
message Payments {
bool enabled = 1;
bytes paymentsEntropy = 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; // color of the QR code itself
}
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;
string givenName = 2;
string familyName = 3;
string avatarUrl = 4;
bool noteToSelfArchived = 5;
bool readReceipts = 6;
bool sealedSenderIndicators = 7;
bool typingIndicators = 8;
bool proxiedLinkPreviews = 9; // Legacy link previews flag
bool noteToSelfMarkedUnread = 10;
bool linkPreviews = 11;
PhoneNumberSharingMode phoneNumberSharingMode = 12;
bool notDiscoverableByPhoneNumber = 13;
repeated PinnedConversation pinnedConversations = 14;
bool preferContactAvatars = 15;
Payments payments = 16;
uint32 universalExpireTimer = 17;
reserved 18; // primarySendsSms
string e164 = 19;
repeated string preferredReactionEmoji = 20;
bytes donorSubscriberID = 21;
string donorSubscriberCurrencyCode = 22;
bool displayBadgesOnProfile = 23;
bool donorSubscriptionManuallyCancelled = 24;
bool keepMutedChatsArchived = 25;
bool myStoryPrivacyHasBeenSet = 26; // Removed 'has' prefix on spec definition to avoid name conflict.
bool viewedOnboardingStory = 27; // Removed 'has' prefix on spec definition to avoid name conflict.
reserved /* deprecatedStoriesDisabled */ 28;
bool storiesDisabled = 29;
OptionalBool storyViewReceiptsEnabled = 30;
bool readOnboardingStory = 31;
reserved /* seenGroupStoryEducation */ 32; // Reserved for a future feature.
string username = 33;
bool completedUsernameOnboarding = 34; // Removed 'has' prefix on spec definition to avoid name conflict.
UsernameLink usernameLink = 35;
reserved /*backupsSubscriberId*/ 36;
reserved /*backupsSubscriberCurrencyCode*/ 37;
reserved /*backupsSubscriptionManuallyCancelled*/ 38;
reserved /*userHasBackup*/ 39;
optional uint64 backupTier = 40;
IAPSubscriberData backupSubscriberData = 41;
optional AvatarColor avatarColor = 42;
}
message StoryDistributionListRecord {
bytes identifier = 1;
string name = 2;
repeated string recipientServiceIds = 3;
uint64 deletedAtTimestamp = 4;
bool allowsReplies = 5;
bool isBlockList = 6;
}
message CallLinkRecord {
bytes rootKey = 1; // 16 bytes
bytes adminPasskey = 2; // Non-empty when the current user is an admin
uint64 deletedAtTimestampMs = 3; // When present and non-zero, `adminPasskey`
// should be cleared
}