fix encoding of status.app links (#3855)

* rm params
* use url data proto
* feat: community channel and user data parsing; improve testing for urls

---------

Co-authored-by: MishkaRogachev <mishkarogachev@gmail.com>
This commit is contained in:
Felicio Mununga 2023-08-14 12:25:42 +02:00 committed by GitHub
parent d61f983d95
commit 57b4036da3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 143 additions and 118 deletions

View File

@ -136,11 +136,21 @@ func (m *Messenger) prepareEncodedCommunityData(community *communities.Community
return "", "", err
}
urlDataProto := &protobuf.URLData{
Content: communityData,
}
urlData, err := proto.Marshal(urlDataProto)
if err != nil {
return "", "", err
}
shortKey, err := m.SerializePublicKey(community.ID())
if err != nil {
return "", "", err
}
encodedData, err := urls.EncodeDataURL(communityData)
encodedData, err := urls.EncodeDataURL(urlData)
if err != nil {
return "", "", err
}
@ -172,13 +182,19 @@ func (m *Messenger) parseCommunityURLWithData(data string, chatKey string) (*URL
return nil, err
}
communityData, err := urls.DecodeDataURL(data)
urlData, err := urls.DecodeDataURL(data)
if err != nil {
return nil, err
}
var urlDataProto protobuf.URLData
err = proto.Unmarshal(urlData, &urlDataProto)
if err != nil {
return nil, err
}
var communityProto protobuf.Community
err = proto.Unmarshal(communityData, &communityProto)
err = proto.Unmarshal(urlDataProto.Content, &communityProto)
if err != nil {
return nil, err
}
@ -284,11 +300,20 @@ func (m *Messenger) prepareEncodedCommunityChannelData(community *communities.Co
return "", "", err
}
urlDataProto := &protobuf.URLData{
Content: channelData,
}
urlData, err := proto.Marshal(urlDataProto)
if err != nil {
return "", "", err
}
shortKey, err := m.SerializePublicKey(community.ID())
if err != nil {
return "", "", err
}
encodedData, err := urls.EncodeDataURL(channelData)
encodedData, err := urls.EncodeDataURL(urlData)
if err != nil {
return "", "", err
}
@ -334,13 +359,19 @@ func (m *Messenger) parseCommunityChannelURLWithData(data string, chatKey string
return nil, err
}
channelData, err := urls.DecodeDataURL(data)
urlData, err := urls.DecodeDataURL(data)
if err != nil {
return nil, err
}
var urlDataProto protobuf.URLData
err = proto.Unmarshal(urlData, &urlDataProto)
if err != nil {
return nil, err
}
var channelProto protobuf.Channel
err = proto.Unmarshal(channelData, &channelProto)
err = proto.Unmarshal(urlDataProto.Content, &channelProto)
if err != nil {
return nil, err
}
@ -421,15 +452,6 @@ func (m *Messenger) parseUserURLWithENS(ensName string) (*URLDataResponse, error
}
func (m *Messenger) prepareEncodedUserData(contact *Contact) (string, string, error) {
userProto := &protobuf.User{
DisplayName: contact.DisplayName,
}
userData, err := proto.Marshal(userProto)
if err != nil {
return "", "", err
}
pk, err := contact.PublicKey()
if err != nil {
return "", "", err
@ -440,7 +462,25 @@ func (m *Messenger) prepareEncodedUserData(contact *Contact) (string, string, er
return "", "", err
}
encodedData, err := urls.EncodeDataURL(userData)
userProto := &protobuf.User{
DisplayName: contact.DisplayName,
}
userData, err := proto.Marshal(userProto)
if err != nil {
return "", "", err
}
urlDataProto := &protobuf.URLData{
Content: userData,
}
urlData, err := proto.Marshal(urlDataProto)
if err != nil {
return "", "", err
}
encodedData, err := urls.EncodeDataURL(urlData)
if err != nil {
return "", "", err
}
@ -463,13 +503,19 @@ func (m *Messenger) ShareUserURLWithData(contactID string) (string, error) {
}
func (m *Messenger) parseUserURLWithData(data string, chatKey string) (*URLDataResponse, error) {
userData, err := urls.DecodeDataURL(data)
urlData, err := urls.DecodeDataURL(data)
if err != nil {
return nil, err
}
var urlDataProto protobuf.URLData
err = proto.Unmarshal(urlData, &urlDataProto)
if err != nil {
return nil, err
}
var userProto protobuf.User
err = proto.Unmarshal(userData, &userProto)
err = proto.Unmarshal(urlDataProto.Content, &userProto)
if err != nil {
return nil, err
}

View File

@ -195,22 +195,32 @@ func (s *MessengerShareUrlsSuite) TestShareCommunityURLWithData() {
expectedURL := fmt.Sprintf("%s/c/%s#%s", baseShareURL, communityData, chatKey)
s.Require().Equal(expectedURL, url)
s.Require().Equal(communityData, "GzAAAETnNgpsRpPBwMzNmQiokxNsTUoRiCDpdc4UDkxk1F7pOu65DV_H8-xat9EQ9g==")
}
func (s *MessengerShareUrlsSuite) TestParseCommunityURLWithData() {
community := s.createCommunity()
communityData, signature, err := s.m.prepareEncodedCommunityData(community)
s.Require().NoError(err)
url := fmt.Sprintf("%s/c/%s#%s", baseShareURL, communityData, signature)
url := "https://status.app/c/iyKACkQKB0Rvb2RsZXMSJ0NvbG9yaW5nIHRoZSB3b3JsZCB3aXRoIGpveSDigKIg4bSXIOKAohiYohsiByMxMzFEMkYqAwEhMwM=#zQ3shYSHp7GoiXaauJMnDcjwU2yNjdzpXLosAWapPS4CFxc11"
urlData, err := s.m.ParseSharedURL(url)
s.Require().NoError(err)
s.Require().NotNil(urlData)
s.Require().NotNil(urlData.Community)
s.Require().Equal("Doodles", urlData.Community.DisplayName)
s.Require().Equal("Coloring the world with joy • ᴗ •", urlData.Community.Description)
s.Require().Equal(uint32(446744), urlData.Community.MembersCount)
s.Require().Equal("#131D2F", urlData.Community.Color)
s.Require().Equal([]uint32{1, 33, 51}, urlData.Community.TagIndices)
}
func (s *MessengerShareUrlsSuite) TestShareAndParseCommunityURLWithData() {
community := s.createCommunity()
url, err := s.m.ShareCommunityURLWithData(community.ID())
s.Require().NoError(err)
urlData, err := s.m.ParseSharedURL(url)
s.Require().NoError(err)
s.Require().Equal(community.Identity().DisplayName, urlData.Community.DisplayName)
s.Require().Equal(community.DescriptionText(), urlData.Community.Description)
s.Require().Equal(uint32(community.MembersCount()), urlData.Community.MembersCount)
@ -279,18 +289,34 @@ func (s *MessengerShareUrlsSuite) TestShareCommunityChannelURLWithData() {
}
func (s *MessengerShareUrlsSuite) TestParseCommunityChannelURLWithData() {
community, channel, channelID := s.createCommunityWithChannel()
communityChannelData, chatKey, err := s.m.prepareEncodedCommunityChannelData(community, channel, channelID)
s.Require().NoError(err)
url := fmt.Sprintf("%s/cc/%s#%s", baseShareURL, communityChannelData, chatKey)
url := "https://status.app/cc/G54AAKwObLdpiGjXnckYzRcOSq0QQAS_CURGfqVU42ceGHCObstUIknTTZDOKF3E8y2MSicncpO7fTskXnoACiPKeejvjtLTGWNxUhlT7fyQS7Jrr33UVHluxv_PLjV2ePGw5GQ33innzeK34pInIgUGs5RjdQifMVmURalxxQKwiuoY5zwIjixWWRHqjHM=#zQ3shYSHp7GoiXaauJMnDcjwU2yNjdzpXLosAWapPS4CFxc11"
urlData, err := s.m.ParseSharedURL(url)
s.Require().NoError(err)
s.Require().NotNil(urlData)
s.Require().NotNil(urlData.Community)
s.Require().Equal("Doodles", urlData.Community.DisplayName)
s.Require().NotNil(urlData.Channel)
s.Require().Equal("🍿", urlData.Channel.Emoji)
s.Require().Equal("design", urlData.Channel.DisplayName)
s.Require().Equal("#131D2F", urlData.Channel.Color)
}
func (s *MessengerShareUrlsSuite) TestShareAndParseCommunityChannelURLWithData() {
community, channel, channelID := s.createCommunityWithChannel()
request := &requests.CommunityChannelShareURL{
CommunityID: community.ID(),
ChannelID: channelID,
}
url, err := s.m.ShareCommunityChannelURLWithData(request)
s.Require().NoError(err)
urlData, err := s.m.ParseSharedURL(url)
s.Require().NoError(err)
s.Require().Equal(community.Identity().DisplayName, urlData.Community.DisplayName)
s.Require().Equal(community.DescriptionText(), urlData.Community.Description)
s.Require().Equal(uint32(community.MembersCount()), urlData.Community.MembersCount)
@ -364,6 +390,18 @@ func (s *MessengerShareUrlsSuite) TestShareUserURLWithENS() {
// s.Require().Equal(contact.Bio, urlData.Contact.DisplayName)
// }
func (s *MessengerShareUrlsSuite) TestParseUserURLWithData() {
url := "https://status.app/u/G10A4B0JdgwyRww90WXtnP1oNH1ZLQNM0yX0Ja9YyAMjrqSZIYINOHCbFhrnKRAcPGStPxCMJDSZlGCKzmZrJcimHY8BbcXlORrElv_BbQEegnMDPx1g9C5VVNl0fE4y#zQ3shwQPhRuDJSjVGVBnTjCdgXy5i9WQaeVPdGJD6yTarJQSj"
urlData, err := s.m.ParseSharedURL(url)
s.Require().NoError(err)
s.Require().NotNil(urlData)
s.Require().NotNil(urlData.Contact)
s.Require().Equal("Mark Cole", urlData.Contact.DisplayName)
s.Require().Equal("Visual designer @Status, cat lover, pizza enthusiast, yoga afficionada", urlData.Contact.Description)
s.Require().Equal("zQ3shwQPhRuDJSjVGVBnTjCdgXy5i9WQaeVPdGJD6yTarJQSj", urlData.Contact.PublicKey)
}
func (s *MessengerShareUrlsSuite) TestShareUserURLWithData() {
_, contact := s.createContact()
@ -375,22 +413,23 @@ func (s *MessengerShareUrlsSuite) TestShareUserURLWithData() {
expectedURL := fmt.Sprintf("%s/u/%s#%s", baseShareURL, userData, chatKey)
s.Require().Equal(expectedURL, url)
s.Require().Equal(userData, "Ow==")
}
func (s *MessengerShareUrlsSuite) TestParseUserURLWithData() {
func (s *MessengerShareUrlsSuite) TestShareAndParseUserURLWithData() {
_, contact := s.createContact()
userData, chatKey, err := s.m.prepareEncodedUserData(contact)
pk, err := contact.PublicKey()
s.Require().NoError(err)
url := fmt.Sprintf("%s/u/%s#%s", baseShareURL, userData, chatKey)
shortKey, err := s.m.SerializePublicKey(crypto.CompressPubkey(pk))
s.Require().NoError(err)
url, err := s.m.ShareUserURLWithData(contact.ID)
s.Require().NoError(err)
urlData, err := s.m.ParseSharedURL(url)
s.Require().NoError(err)
s.Require().NotNil(urlData)
s.Require().NotNil(urlData.Contact)
s.Require().Equal(contact.DisplayName, urlData.Contact.DisplayName)
s.Require().Equal(contact.Bio, urlData.Contact.Description)
s.Require().Equal(shortKey, urlData.Contact.PublicKey)
}

View File

@ -265,61 +265,11 @@ func (m *URLData) GetContent() []byte {
return nil
}
// Field on CommunityDescription, CommunityChat and ContactCodeAdvertisement
type URLParams struct {
EncodedUrlData string `protobuf:"bytes,1,opt,name=encoded_url_data,json=encodedUrlData,proto3" json:"encoded_url_data,omitempty"`
// Signature of encoded URL data
EncodedSignature string `protobuf:"bytes,2,opt,name=encoded_signature,json=encodedSignature,proto3" json:"encoded_signature,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *URLParams) Reset() { *m = URLParams{} }
func (m *URLParams) String() string { return proto.CompactTextString(m) }
func (*URLParams) ProtoMessage() {}
func (*URLParams) Descriptor() ([]byte, []int) {
return fileDescriptor_5f1e15b5f0115710, []int{4}
}
func (m *URLParams) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_URLParams.Unmarshal(m, b)
}
func (m *URLParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_URLParams.Marshal(b, m, deterministic)
}
func (m *URLParams) XXX_Merge(src proto.Message) {
xxx_messageInfo_URLParams.Merge(m, src)
}
func (m *URLParams) XXX_Size() int {
return xxx_messageInfo_URLParams.Size(m)
}
func (m *URLParams) XXX_DiscardUnknown() {
xxx_messageInfo_URLParams.DiscardUnknown(m)
}
var xxx_messageInfo_URLParams proto.InternalMessageInfo
func (m *URLParams) GetEncodedUrlData() string {
if m != nil {
return m.EncodedUrlData
}
return ""
}
func (m *URLParams) GetEncodedSignature() string {
if m != nil {
return m.EncodedSignature
}
return ""
}
func init() {
proto.RegisterType((*Community)(nil), "protobuf.Community")
proto.RegisterType((*Channel)(nil), "protobuf.Channel")
proto.RegisterType((*User)(nil), "protobuf.User")
proto.RegisterType((*URLData)(nil), "protobuf.URLData")
proto.RegisterType((*URLParams)(nil), "protobuf.URLParams")
}
func init() {
@ -327,27 +277,24 @@ func init() {
}
var fileDescriptor_5f1e15b5f0115710 = []byte{
// 342 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x92, 0xb1, 0x4e, 0xc3, 0x30,
0x10, 0x86, 0x15, 0xda, 0xb4, 0xe4, 0xd2, 0x54, 0x60, 0x3a, 0x78, 0x23, 0xa4, 0x4b, 0x24, 0xa4,
0x20, 0x60, 0x64, 0xa3, 0x2c, 0x48, 0x15, 0x42, 0x46, 0x59, 0x58, 0x22, 0x27, 0x31, 0xc5, 0x28,
0xb6, 0x2b, 0xc7, 0x19, 0xfa, 0x4e, 0xbc, 0x04, 0x6f, 0x86, 0x70, 0x62, 0xca, 0xc2, 0xd6, 0x29,
0x77, 0x9f, 0x4e, 0x7f, 0x3e, 0xfd, 0x32, 0xcc, 0x3b, 0xdd, 0x14, 0x35, 0x35, 0x34, 0xdb, 0x6a,
0x65, 0x14, 0x3a, 0xb6, 0x9f, 0xb2, 0x7b, 0x4b, 0x3e, 0x3d, 0x08, 0x56, 0x4a, 0x88, 0x4e, 0x72,
0xb3, 0x43, 0x17, 0x30, 0xab, 0x79, 0xbb, 0x6d, 0xe8, 0xae, 0x90, 0x54, 0x30, 0xec, 0xc5, 0x5e,
0x1a, 0x90, 0x70, 0x60, 0x4f, 0x54, 0x30, 0x14, 0x43, 0x58, 0xb3, 0xb6, 0xd2, 0x7c, 0x6b, 0xb8,
0x92, 0xf8, 0x68, 0xb8, 0xd8, 0x23, 0xb4, 0x84, 0x48, 0x30, 0x51, 0x32, 0xdd, 0x16, 0x95, 0xea,
0xa4, 0xc1, 0xa3, 0xd8, 0x4b, 0x23, 0x32, 0x1b, 0xe0, 0xea, 0x87, 0xa1, 0x05, 0xf8, 0x95, 0x6a,
0x94, 0xc6, 0x63, 0x1b, 0xd0, 0x2f, 0xe8, 0x1c, 0x42, 0x43, 0x37, 0x05, 0x97, 0x35, 0xaf, 0x58,
0x8b, 0xfd, 0x78, 0x94, 0x46, 0x04, 0x0c, 0xdd, 0x3c, 0xf6, 0x24, 0xf9, 0xf2, 0x60, 0xba, 0x7a,
0xa7, 0x52, 0xb2, 0xe6, 0x30, 0xb2, 0x0b, 0xf0, 0x99, 0x50, 0x1f, 0xdc, 0x4a, 0x06, 0xa4, 0x5f,
0xfe, 0xb1, 0xbb, 0x86, 0xa0, 0x72, 0x55, 0x61, 0x3f, 0xf6, 0xd2, 0xf0, 0xe6, 0x2c, 0x73, 0x4d,
0x66, 0xbf, 0x2d, 0x92, 0xfd, 0x15, 0x42, 0x30, 0xee, 0x3a, 0x5e, 0xe3, 0x89, 0xcd, 0xb1, 0x73,
0x42, 0x61, 0x9c, 0xb7, 0x4c, 0x1f, 0xcc, 0xbf, 0x37, 0x1d, 0xfd, 0x31, 0x4d, 0x96, 0x30, 0xcd,
0xc9, 0xfa, 0x81, 0x1a, 0x8a, 0x30, 0x4c, 0x2b, 0x25, 0x0d, 0x93, 0xc6, 0xfe, 0x60, 0x46, 0xdc,
0x9a, 0x94, 0x10, 0xe4, 0x64, 0xfd, 0x4c, 0x35, 0x15, 0x2d, 0x4a, 0xe1, 0x84, 0xc9, 0x4a, 0xd5,
0xac, 0x2e, 0xdc, 0x5b, 0x19, 0x84, 0xe6, 0x03, 0xcf, 0x75, 0x63, 0x03, 0x2f, 0xe1, 0xd4, 0x5d,
0xb6, 0x7c, 0x23, 0xa9, 0xe9, 0x34, 0x1b, 0xcc, 0x5c, 0xc4, 0x8b, 0xe3, 0xf7, 0xd1, 0x6b, 0x98,
0x5d, 0xdd, 0xb9, 0x8e, 0xca, 0x89, 0x9d, 0x6e, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0xe0, 0xcf,
0x99, 0x77, 0x90, 0x02, 0x00, 0x00,
// 295 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x90, 0xb1, 0x4e, 0xeb, 0x30,
0x14, 0x86, 0xe5, 0xdb, 0xa6, 0xbd, 0x39, 0x69, 0x18, 0x4c, 0x07, 0x6f, 0x84, 0x74, 0xc9, 0x14,
0x04, 0x8c, 0x6c, 0x94, 0x05, 0x09, 0x31, 0x58, 0xea, 0xc2, 0x12, 0x39, 0x8e, 0x29, 0x46, 0xb1,
0x1d, 0x39, 0xf6, 0xd0, 0x77, 0xe2, 0x25, 0x78, 0x33, 0x84, 0x93, 0x50, 0x16, 0xb6, 0x4e, 0x3e,
0xff, 0xa7, 0xa3, 0xe3, 0x4f, 0x3f, 0x9c, 0x79, 0xdb, 0x56, 0x0d, 0x73, 0xac, 0xec, 0xac, 0x71,
0x06, 0xff, 0x0f, 0x4f, 0xed, 0x5f, 0xf3, 0x0f, 0x04, 0xf1, 0xd6, 0x28, 0xe5, 0xb5, 0x74, 0x07,
0x7c, 0x09, 0xab, 0x46, 0xf6, 0x5d, 0xcb, 0x0e, 0x95, 0x66, 0x4a, 0x10, 0x94, 0xa1, 0x22, 0xa6,
0xc9, 0xc8, 0x9e, 0x99, 0x12, 0x38, 0x83, 0xa4, 0x11, 0x3d, 0xb7, 0xb2, 0x73, 0xd2, 0x68, 0xf2,
0x6f, 0xdc, 0x38, 0x22, 0xbc, 0x81, 0x54, 0x09, 0x55, 0x0b, 0xdb, 0x57, 0xdc, 0x78, 0xed, 0xc8,
0x2c, 0x43, 0x45, 0x4a, 0x57, 0x23, 0xdc, 0x7e, 0x33, 0xbc, 0x86, 0x88, 0x9b, 0xd6, 0x58, 0x32,
0x0f, 0x07, 0x86, 0x80, 0x2f, 0x20, 0x71, 0x6c, 0x5f, 0x49, 0xdd, 0x48, 0x2e, 0x7a, 0x12, 0x65,
0xb3, 0x22, 0xa5, 0xe0, 0xd8, 0xfe, 0x71, 0x20, 0xf9, 0x27, 0x82, 0xe5, 0xf6, 0x8d, 0x69, 0x2d,
0xda, 0xd3, 0xc8, 0xae, 0x21, 0x12, 0xca, 0xbc, 0xcb, 0x20, 0x19, 0xd3, 0x21, 0xfc, 0x61, 0x77,
0x0d, 0x31, 0x9f, 0xaa, 0x22, 0x51, 0x86, 0x8a, 0xe4, 0xe6, 0xbc, 0x9c, 0x9a, 0x2c, 0x7f, 0x5a,
0xa4, 0xc7, 0x2d, 0x8c, 0x61, 0xee, 0xbd, 0x6c, 0xc8, 0x22, 0xdc, 0x09, 0x73, 0xce, 0x60, 0xbe,
0xeb, 0x85, 0x3d, 0x99, 0xff, 0x60, 0x3a, 0xfb, 0x65, 0x9a, 0x6f, 0x60, 0xb9, 0xa3, 0x4f, 0x0f,
0xcc, 0x31, 0x4c, 0x60, 0xc9, 0x8d, 0x76, 0x42, 0xbb, 0xf0, 0xc1, 0x8a, 0x4e, 0xf1, 0x3e, 0x7d,
0x49, 0xca, 0xab, 0xbb, 0xc9, 0xbf, 0x5e, 0x84, 0xe9, 0xf6, 0x2b, 0x00, 0x00, 0xff, 0xff, 0xd1,
0x08, 0xbf, 0x32, 0x2c, 0x02, 0x00, 0x00,
}

View File

@ -30,10 +30,3 @@ message URLData {
// Community, Channel, or User
bytes content = 1;
}
// Field on CommunityDescription, CommunityChat and ContactCodeAdvertisement
message URLParams {
string encoded_url_data = 1;
// Signature of encoded URL data
string encoded_signature = 2;
}