Skip to content

Commit bb077db

Browse files
backup: add avatarColor/svrPin support
Co-authored-by: andrew-signal <[email protected]>
1 parent 2ebd7cd commit bb077db

File tree

11 files changed

+108
-16
lines changed

11 files changed

+108
-16
lines changed

RELEASE_NOTES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ v0.67.2
66
- Abstract Server(Private/Public)Params from endorsements. Reduces dependencies in clients and issuing servers.
77
- Add EndorsementPublicRootKey accessor to ServerPublicParams.
88
- Node: ChatListener has a new optional callback for server alerts. (iOS and Android coming later.)
9+
- Add support for avatarColor/svrPin fields in backup protos

rust/message-backup/src/backup/account_data.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ pub struct AccountData<M: Method + ReferencedTypes> {
4141
pub avatar_url_path: M::Value<String>,
4242
pub donation_subscription: M::Value<Option<Subscription>>,
4343
pub backup_subscription: M::Value<Option<IapSubscriberData>>,
44+
pub svr_pin: M::Value<String>,
4445
}
4546

4647
#[derive(Debug, serde::Serialize)]
@@ -181,6 +182,7 @@ impl<M: Method + ReferencedTypes, C: ReportUnusualTimestamp> TryFromWith<proto::
181182
avatarUrlPath,
182183
donationSubscriberData,
183184
backupsSubscriberData,
185+
svrPin,
184186
special_fields: _,
185187
} = proto;
186188

@@ -222,6 +224,7 @@ impl<M: Method + ReferencedTypes, C: ReportUnusualTimestamp> TryFromWith<proto::
222224
avatar_url_path: M::value(avatarUrlPath),
223225
donation_subscription: M::value(donation_subscription),
224226
backup_subscription: M::value(backup_subscription),
227+
svr_pin: M::value(svrPin),
225228
})
226229
}
227230
}
@@ -538,6 +541,7 @@ mod test {
538541
subscription_id: IapSubscriptionId::IosAppStoreOriginalTransactionId(5),
539542
}),
540543
donation_subscription: None,
544+
svr_pin: "".to_string(),
541545
}
542546
}
543547
}

rust/message-backup/src/backup/expected_serialized_backup.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@
6161
"subscription_id": {
6262
"IosAppStoreOriginalTransactionId": 5
6363
}
64-
}
64+
},
65+
"svr_pin": ""
6566
},
6667
"recipients": [],
6768
"chats": [],

rust/message-backup/src/backup/recipient.rs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ pub enum Destination<R> {
236236
Group(GroupData),
237237
#[serde(bound(serialize = "DistributionListItem<R>: serde::Serialize"))]
238238
DistributionList(DistributionListItem<R>),
239-
Self_,
239+
Self_(SelfData),
240240
ReleaseNotes,
241241
CallLink(CallLink),
242242
}
@@ -300,6 +300,8 @@ pub struct ContactData {
300300
pub system_given_name: String,
301301
pub system_family_name: String,
302302
pub system_nickname: String,
303+
#[serde(serialize_with = "serialize::optional_enum_as_string")]
304+
pub avatar_color: Option<proto::AvatarColor>,
303305
}
304306

305307
#[derive(Clone, Debug, serde::Serialize)]
@@ -309,6 +311,13 @@ pub struct ContactName {
309311
pub family_name: String,
310312
}
311313

314+
#[derive(Clone, Debug, serde::Serialize)]
315+
#[cfg_attr(test, derive(PartialEq))]
316+
pub struct SelfData {
317+
#[serde(serialize_with = "serialize::optional_enum_as_string")]
318+
pub avatar_color: Option<proto::AvatarColor>,
319+
}
320+
312321
#[derive(Clone, Debug, serde::Serialize)]
313322
#[cfg_attr(test, derive(PartialEq))]
314323
pub enum DistributionListItem<Recipient> {
@@ -378,7 +387,7 @@ impl<R> From<Destination<R>> for MinimalRecipientData {
378387
distribution_id, ..
379388
},
380389
) => Self::DistributionList { distribution_id },
381-
Destination::Self_ => Self::Self_,
390+
Destination::Self_(_) => Self::Self_,
382391
Destination::ReleaseNotes => Self::ReleaseNotes,
383392
Destination::CallLink(CallLink { root_key, .. }) => Self::CallLink { root_key },
384393
}
@@ -431,7 +440,7 @@ impl<R> AsRef<DestinationKind> for Destination<R> {
431440
Destination::Contact(_) => &DestinationKind::Contact,
432441
Destination::Group(_) => &DestinationKind::Group,
433442
Destination::DistributionList(_) => &DestinationKind::DistributionList,
434-
Destination::Self_ => &DestinationKind::Self_,
443+
Destination::Self_(_) => &DestinationKind::Self_,
435444
Destination::ReleaseNotes => &DestinationKind::ReleaseNotes,
436445
Destination::CallLink(_) => &DestinationKind::CallLink,
437446
}
@@ -459,7 +468,14 @@ impl<R: Clone, C: LookupPair<RecipientId, MinimalRecipientData, R> + ReportUnusu
459468
RecipientDestination::DistributionList(list) => {
460469
Destination::DistributionList(list.try_into_with(context)?)
461470
}
462-
RecipientDestination::Self_(proto::Self_ { special_fields: _ }) => Destination::Self_,
471+
RecipientDestination::Self_(proto::Self_ {
472+
avatarColor,
473+
special_fields: _,
474+
}) => {
475+
// The color is allowed to be unset.
476+
let avatar_color = avatarColor.map(|v| v.enum_value_or_default());
477+
Destination::Self_(SelfData { avatar_color })
478+
}
463479
RecipientDestination::ReleaseNotes(proto::ReleaseNotes { special_fields: _ }) => {
464480
Destination::ReleaseNotes
465481
}
@@ -493,6 +509,7 @@ impl<C: ReportUnusualTimestamp> TryFromWith<proto::Contact, C> for ContactData {
493509
systemGivenName,
494510
systemFamilyName,
495511
systemNickname,
512+
avatarColor,
496513
special_fields: _,
497514
} = value;
498515

@@ -595,6 +612,9 @@ impl<C: ReportUnusualTimestamp> TryFromWith<proto::Contact, C> for ContactData {
595612
)
596613
.transpose()?;
597614

615+
// The color is allowed to be unset.
616+
let avatar_color = avatarColor.map(|v| v.enum_value_or_default());
617+
598618
Ok(Self {
599619
aci,
600620
pni,
@@ -615,6 +635,7 @@ impl<C: ReportUnusualTimestamp> TryFromWith<proto::Contact, C> for ContactData {
615635
system_given_name: systemGivenName,
616636
system_family_name: systemFamilyName,
617637
system_nickname: systemNickname,
638+
avatar_color,
618639
})
619640
}
620641
}
@@ -859,6 +880,7 @@ mod test {
859880
system_family_name: "FamilySystemName".to_owned(),
860881
system_nickname: "SystemNickName".to_owned(),
861882
note: "nb".into(),
883+
avatar_color: None,
862884
}
863885
}
864886
}
@@ -882,7 +904,7 @@ mod test {
882904

883905
assert_eq!(
884906
Destination::try_from_with(recipient, &TestContext::default()),
885-
Ok(Destination::Self_)
907+
Ok(Destination::Self_(SelfData { avatar_color: None }))
886908
)
887909
}
888910

rust/message-backup/src/backup/recipient/group.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,8 @@ pub struct GroupData {
291291
pub story_send_mode: proto::group::StorySendMode,
292292
pub snapshot: GroupSnapshot,
293293
pub blocked: bool,
294+
#[serde(serialize_with = "serialize::optional_enum_as_string")]
295+
pub avatar_color: Option<proto::AvatarColor>,
294296
_limit_construction_to_module: (),
295297
}
296298

@@ -304,6 +306,7 @@ impl<C: ReportUnusualTimestamp> TryFromWith<proto::Group, C> for GroupData {
304306
storySendMode,
305307
snapshot,
306308
blocked,
309+
avatarColor,
307310
special_fields: _,
308311
} = value;
309312

@@ -317,6 +320,9 @@ impl<C: ReportUnusualTimestamp> TryFromWith<proto::Group, C> for GroupData {
317320
| proto::group::StorySendMode::ENABLED) => s,
318321
};
319322

323+
// The color is allowed to be unset.
324+
let avatar_color = avatarColor.map(|v| v.enum_value_or_default());
325+
320326
let snapshot = snapshot
321327
.into_option()
322328
.ok_or(GroupError::MissingSnapshot)?
@@ -329,6 +335,7 @@ impl<C: ReportUnusualTimestamp> TryFromWith<proto::Group, C> for GroupData {
329335
story_send_mode,
330336
snapshot,
331337
blocked,
338+
avatar_color,
332339
_limit_construction_to_module: (),
333340
})
334341
}
@@ -434,6 +441,7 @@ mod test {
434441
_limit_construction_to_module: (),
435442
},
436443
blocked: false,
444+
avatar_color: None,
437445
_limit_construction_to_module: (),
438446
}
439447
}

rust/message-backup/src/backup/serialize.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,14 @@ pub(crate) fn enum_as_string<S: Serializer>(
109109
format!("{source:?}").serialize(serializer)
110110
}
111111

112+
/// Serializes [`protobuf::Enum`] types as strings.
113+
pub(crate) fn optional_enum_as_string<S: Serializer>(
114+
source: &Option<impl protobuf::Enum>,
115+
serializer: S,
116+
) -> Result<S::Ok, S::Error> {
117+
(*source).map(|v| format!("{v:?}")).serialize(serializer)
118+
}
119+
112120
/// Serializes an optional bytestring as hex.
113121
pub(crate) fn optional_hex<S: Serializer>(
114122
value: &Option<impl AsRef<[u8]>>,
@@ -216,15 +224,15 @@ impl SerializeOrder for FullRecipientData {
216224
(Destination::CallLink(lhs), Destination::CallLink(rhs)) => {
217225
lhs.root_key.cmp(&rhs.root_key)
218226
}
219-
(Destination::Self_, Destination::Self_)
227+
(Destination::Self_(_), Destination::Self_(_))
220228
| (Destination::ReleaseNotes, Destination::ReleaseNotes) => {
221229
std::cmp::Ordering::Equal
222230
}
223231
_ => unreachable!("discriminants are equal"),
224232
}
225233
} else {
226234
let discriminant = |value: &Destination<_>| match value {
227-
Destination::Self_ => 0,
235+
Destination::Self_(_) => 0,
228236
Destination::ReleaseNotes => 1,
229237
Destination::Contact(_) => 2,
230238
Destination::Group(_) => 3,

rust/message-backup/src/backup/testutil.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::backup::chat::PinOrder;
1212
use crate::backup::frame::RecipientId;
1313
use crate::backup::method::{Lookup, LookupPair};
1414
use crate::backup::recipient::group::GroupData;
15-
use crate::backup::recipient::{self, ContactData, Destination, FullRecipientData};
15+
use crate::backup::recipient::{self, ContactData, Destination, FullRecipientData, SelfData};
1616
use crate::backup::time::{ReportUnusualTimestamp, Timestamp, TimestampIssue};
1717
use crate::backup::{BackupMeta, Purpose};
1818
use crate::proto::backup as proto;
@@ -40,7 +40,7 @@ impl BackupMeta {
4040
}
4141
}
4242
static SELF_RECIPIENT: LazyLock<FullRecipientData> =
43-
LazyLock::new(|| FullRecipientData::new(Destination::Self_));
43+
LazyLock::new(|| FullRecipientData::new(Destination::Self_(SelfData { avatar_color: None })));
4444
static CONTACT_RECIPIENT: LazyLock<FullRecipientData> = LazyLock::new(|| {
4545
FullRecipientData::new(Destination::Contact(ContactData::from_proto_test_data()))
4646
});
@@ -64,6 +64,7 @@ static E164_ONLY_RECIPIENT: LazyLock<FullRecipientData> = LazyLock::new(|| {
6464
system_given_name: "".to_owned(),
6565
system_family_name: "".to_owned(),
6666
system_nickname: "".to_owned(),
67+
avatar_color: None,
6768
note: "".into(),
6869
}))
6970
});
@@ -89,6 +90,7 @@ static PNI_ONLY_RECIPIENT: LazyLock<FullRecipientData> = LazyLock::new(|| {
8990
system_family_name: "".to_owned(),
9091
system_nickname: "".to_owned(),
9192
nickname: None,
93+
avatar_color: None,
9294
note: "".into(),
9395
}))
9496
});

rust/message-backup/src/proto/backup.proto

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ message AccountData {
117117
reserved /*backupsSubscriberData*/ 8; // A deprecated format
118118
AccountSettings accountSettings = 9;
119119
IAPSubscriberData backupsSubscriberData = 10;
120+
string svrPin = 11;
120121
}
121122

122123
message Recipient {
@@ -132,6 +133,30 @@ message Recipient {
132133
}
133134
}
134135

136+
// If unset - computed as the value of the first byte of SHA-256(msg=CONTACT_ID)
137+
// modulo the count of colors. Once set the avatar color for a recipient is
138+
// never recomputed or changed.
139+
//
140+
// `CONTACT_ID` is the first available identifier from the list:
141+
// - ServiceIdToBinary(ACI)
142+
// - E164
143+
// - ServiceIdToBinary(PNI)
144+
// - Group Id
145+
enum AvatarColor {
146+
A100 = 0;
147+
A110 = 1;
148+
A120 = 2;
149+
A130 = 3;
150+
A140 = 4;
151+
A150 = 5;
152+
A160 = 6;
153+
A170 = 7;
154+
A180 = 8;
155+
A190 = 9;
156+
A200 = 10;
157+
A210 = 11;
158+
}
159+
135160
message Contact {
136161
enum IdentityState {
137162
DEFAULT = 0; // A valid value -- indicates unset by the user
@@ -180,6 +205,7 @@ message Contact {
180205
string systemGivenName = 18;
181206
string systemFamilyName = 19;
182207
string systemNickname = 20;
208+
optional AvatarColor avatarColor = 21;
183209
}
184210

185211
message Group {
@@ -195,6 +221,7 @@ message Group {
195221
StorySendMode storySendMode = 4;
196222
GroupSnapshot snapshot = 5;
197223
bool blocked = 6;
224+
optional AvatarColor avatarColor = 7;
198225

199226
// These are simply plaintext copies of the groups proto from Groups.proto.
200227
// They should be kept completely in-sync with Groups.proto.
@@ -274,7 +301,9 @@ message Group {
274301
}
275302
}
276303

277-
message Self {}
304+
message Self {
305+
optional AvatarColor avatarColor = 1;
306+
}
278307

279308
message ReleaseNotes {}
280309

rust/message-backup/src/scramble.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ impl Visit<Scrambler> for proto::AccountData {
223223
donationSubscriberData,
224224
accountSettings,
225225
backupsSubscriberData,
226+
svrPin,
226227
special_fields: _,
227228
} = self;
228229

@@ -239,6 +240,7 @@ impl Visit<Scrambler> for proto::AccountData {
239240
donationSubscriberData.accept(visitor);
240241
accountSettings.accept(visitor);
241242
backupsSubscriberData.accept(visitor);
243+
svrPin.randomize(&mut visitor.rng);
242244
}
243245
}
244246

@@ -489,6 +491,7 @@ impl Visit<Scrambler> for proto::Contact {
489491
systemFamilyName,
490492
systemNickname,
491493
note,
494+
avatarColor: _,
492495
special_fields: _,
493496
} = self;
494497

@@ -570,6 +573,7 @@ impl Visit<Scrambler> for proto::Group {
570573
storySendMode: _,
571574
snapshot,
572575
blocked: _,
576+
avatarColor: _,
573577
special_fields: _,
574578
} = self;
575579
masterKey.randomize(&mut visitor.rng);
@@ -724,7 +728,10 @@ impl Visit<Scrambler> for proto::DistributionListItem {
724728

725729
impl Visit<Scrambler> for proto::Self_ {
726730
fn accept(&mut self, _visitor: &mut Scrambler) {
727-
let Self { special_fields: _ } = self;
731+
let Self {
732+
avatarColor: _,
733+
special_fields: _,
734+
} = self;
728735
}
729736
}
730737

rust/message-backup/tests/res/canonical-backup.expected.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,15 @@
4646
"currency_code": "USD",
4747
"manually_canceled": true
4848
},
49-
"backup_subscription": null
49+
"backup_subscription": null,
50+
"svr_pin": ""
5051
},
5152
"recipients": [
52-
"Self_",
53+
{
54+
"Self_": {
55+
"avatar_color": null
56+
}
57+
},
5358
"ReleaseNotes",
5459
{
5560
"DistributionList": {

0 commit comments

Comments
 (0)