Peer invitation refactor, Contact invitationId, Qrcode compression

This commit is contained in:
ycc
2022-11-27 21:08:34 +01:00
parent 2516b41597
commit 8195a22300
10 changed files with 466 additions and 128 deletions

76
client/config.go Normal file
View File

@ -0,0 +1,76 @@
package client
import (
"encoding/json"
"io/ioutil"
"sync"
)
type Config struct {
// UserConfig
SavePassword bool `json:"save_password,omitempty"`
SavedPassword string `json:"saved_password,omitempty"`
// Technical
StoragePath string `json:"storage_path,omitempty"`
MaxIdsPerUser int `json:"max_ids_per_user,omitempty"`
MsgDbRollingPeriod int `json:"msg_db_rolling_period,omitempty"`
Chunksize int `json:"chunksize,omitempty"`
ServerPollInterval int `json:"server_poll_interval,omitempty"`
// GUI
LastOpenChat string `json:"last_open_chat,omitempty"`
SoundNotification bool `json:"sound_notification,omitempty"`
DefaultNotificationSound string `json:"default_notification_sound,omitempty"`
NotificationVibe string `json:"notification_vibe,omitempty"`
DefaultNotificationVibe string `json:"default_notification_vibe,omitempty"`
NotificationLED string `json:"notification_led,omitempty"`
DefaultNotificationLEDColor string `json:"default_notification_led_color,omitempty"`
VisualNotification bool `json:"visual_notification,omitempty"`
VisualNotifiactionModes string `json:"visual_notifiaction_modes,omitempty"`
PrivateChatNotifiactions bool `json:"private_chat_notifiactions,omitempty"`
GroupChatNotifiactions bool `json:"group_chat_notifiactions,omitempty"`
ChannelNotifications bool `json:"channel_notifications,omitempty"`
// Inner
memoryPassword string `json:"memory_password,omitempty"`
}
var instance *Config
var once sync.Once
func GetConfig() *Config {
once.Do(func() {
instance = &Config{}
})
return instance
}
func (c *Config) Load(filename string) error {
data, err := ioutil.ReadFile(filename)
if err != nil {
return err
}
err = json.Unmarshal(data, c)
if err != nil {
return err
}
return nil
}
func (c *Config) Save(filename string) error {
data, err := json.Marshal(c)
if err != nil {
return err
}
ioutil.WriteFile(filename, data, 0644)
if err != nil {
return err
}
return nil
}
func (c *Config) SetMemPass(pass string) {
c.memoryPassword = pass
}
func (c *Config) GetMemPass() string {
return c.memoryPassword
}

19
client/config_test.go Normal file
View File

@ -0,0 +1,19 @@
package client
import (
"testing"
)
func TestConfigSave(t *testing.T) {
c := GetConfig()
c.memoryPassword = "hideme"
c.Chunksize = 10000000
c.SavePassword = true
c.SavedPassword = "stupid"
c.Save("test.cfg")
}
func TestConfigLoad(t *testing.T) {
_ = GetConfig().Load("test.cfg")
println(GetConfig().Chunksize)
}

View File

@ -2,10 +2,12 @@ package client
import (
"encoding/json"
"errors"
"io/ioutil"
"forge.redroom.link/yves/meowlib"
"github.com/ProtonMail/gopenpgp/v2/helper"
"github.com/google/uuid"
)
const key = "3pw0c8#6ZG8{75b5;3?fe80$2"
@ -31,30 +33,64 @@ func CreateIdentity(nickname string) *Identity {
return &id
}
func (id *Identity) InvitePeer(MyName string, ContactName string, MessageServerIdxs []int) (*Peer, *meowlib.ContactCard) {
func (id *Identity) InvitePeer(MyName string, ContactName string, MessageServerIdxs []int) *meowlib.ContactCard {
var peer Peer
var myContactCard meowlib.ContactCard
peer.Me = meowlib.NewKeyPair()
peer.EncryptionKp = meowlib.NewKeyPair()
peer.LookupKp = meowlib.NewKeyPair()
peer.MyIdentity = meowlib.NewKeyPair()
peer.MyEncryptionKp = meowlib.NewKeyPair()
peer.MyLookupKp = meowlib.NewKeyPair()
peer.Name = ContactName
peer.InvitationId = uuid.New().String()
for _, i := range MessageServerIdxs {
srv := id.MessageServers.Servers[i].ServerData
myContactCard.PullServers = append(myContactCard.PullServers, &srv)
}
myContactCard.Name = MyName
myContactCard.ContactPublicKey = peer.Me.Public
myContactCard.EncryptionPublicKey = peer.EncryptionKp.Public
myContactCard.LookupPublicKey = peer.LookupKp.Public
myContactCard.ContactPublicKey = peer.MyIdentity.Public
myContactCard.EncryptionPublicKey = peer.MyEncryptionKp.Public
myContactCard.LookupPublicKey = peer.MyLookupKp.Public
myContactCard.InvitationId = peer.InvitationId
id.Peers = append(id.Peers, peer)
return &myContactCard
}
func (id *Identity) AnswerInvitation(MyName string, ContactName string, MessageServerIdxs []int, ReceivedContact *meowlib.ContactCard) *meowlib.ContactCard {
var peer Peer
var myContactCard meowlib.ContactCard
peer.MyIdentity = meowlib.NewKeyPair()
peer.MyEncryptionKp = meowlib.NewKeyPair()
peer.MyLookupKp = meowlib.NewKeyPair()
if ContactName != "" {
peer.Name = ContactName
} else {
peer.Name = ReceivedContact.Name
}
peer.Contact = *ReceivedContact
for _, i := range MessageServerIdxs {
srv := id.MessageServers.Servers[i].ServerData
myContactCard.PullServers = append(myContactCard.PullServers, &srv)
}
myContactCard.Name = MyName
myContactCard.ContactPublicKey = peer.MyIdentity.Public
myContactCard.EncryptionPublicKey = peer.MyEncryptionKp.Public
myContactCard.LookupPublicKey = peer.MyLookupKp.Public
myContactCard.InvitationId = peer.InvitationId
id.Peers = append(id.Peers, peer)
return &id.Peers[len(id.Peers)-1], &myContactCard
return &myContactCard
}
func (*Identity) FinalizeInvitation(peer *Peer, ReceivedContact *meowlib.ContactCard) {
peer.Contact = *ReceivedContact
func (id *Identity) FinalizeInvitation(ReceivedContact *meowlib.ContactCard) error {
for i, p := range id.Peers {
if p.InvitationId == ReceivedContact.InvitationId {
id.Peers[i].Contact = *ReceivedContact
return nil
}
}
return errors.New("no matching contact found for invitationId " + ReceivedContact.InvitationId)
}
func LoadIdentity(file string) (*Identity, error) {

View File

@ -2,6 +2,8 @@ package client
import (
"fmt"
"io"
"os"
"time"
"forge.redroom.link/yves/meowlib"
@ -13,11 +15,13 @@ type Peer struct {
Name string `json:"name,omitempty"`
// Conversation []InternalMessage `json:"conversation,omitempty"`
// My own keys for that peer
Me meowlib.KeyPair `json:"me,omitempty"`
EncryptionKp meowlib.KeyPair `json:"conversation_kp,omitempty"`
LookupKp meowlib.KeyPair `json:"lookup_kp,omitempty"`
MyIdentity meowlib.KeyPair `json:"my_identity,omitempty"`
MyEncryptionKp meowlib.KeyPair `json:"my_encryption_kp,omitempty"`
MyLookupKp meowlib.KeyPair `json:"my_lookup_kp,omitempty"`
MyPullServers []meowlib.Server `json:"my_pull_servers,omitempty"`
// Peer keys and infos
Contact meowlib.ContactCard `json:"contact,omitempty"`
Contact meowlib.ContactCard `json:"contact,omitempty"`
InvitationId string `json:"invitation_id,omitempty"`
// Internal management attributes
Visible bool `json:"visible,omitempty"`
VisiblePassword string `json:"visible_password,omitempty"`
@ -26,7 +30,7 @@ type Peer struct {
MessageNotification string `json:"message_notification,omitempty"`
OnionMode bool `json:"onion_mode,omitempty"`
LastMessage time.Time `json:"last_message,omitempty"`
MessageDb string `json:"message_db,omitempty"` // sql url for messages storage
DbIds []string `json:"db_ids,omitempty"`
DbPassword string `json:"db_password,omitempty"`
}
@ -57,13 +61,59 @@ func (pl *PeerList) GetFromName(name string) *Peer {
func (p *Peer) BuildSimpleUserUMessage(message []byte) (*meowlib.UserMessage, error) {
var msg meowlib.UserMessage
msg.From = p.Me.Public
msg.From = p.MyIdentity.Public
msg.Data = message
msg.Type = "1"
msg.Status = &meowlib.UserMessage_ConversationStatus{}
msg.Status.LocalUuid = uuid.New().String()
return &msg, nil
}
func (p *Peer) BuildFileMessage(filename string, message []byte) ([]meowlib.UserMessage, error) {
var msgs []meowlib.UserMessage
fi, err := os.Stat(filename)
if err != nil {
return nil, err
}
file, err := os.Open(filename)
if err != nil {
return nil, err
}
defer file.Close()
// declare chunk size
maxSz := GetConfig().Chunksize
// create buffer
b := make([]byte, maxSz)
chunk := 0
for {
// read content to buffer
readTotal, err := file.Read(b)
if err != nil {
if err != io.EOF {
return nil, err
}
break
}
var msg meowlib.UserMessage
msg.From = p.MyIdentity.Public
msg.File.Filename = fi.Name()
msg.File.Chunk = uint32(chunk)
msg.File.Data = b[:readTotal]
msg.File.Size = uint64(fi.Size())
msg.Type = "2"
if chunk == 0 {
msg.Status = &meowlib.UserMessage_ConversationStatus{}
msg.Status.LocalUuid = uuid.New().String()
}
msgs = append(msgs, msg)
chunk++
}
return msgs, nil
}
func (p *Peer) SerializeUserMessage(msg *meowlib.UserMessage) ([]byte, error) {
out, err := proto.Marshal(msg)
if err != nil {
@ -74,7 +124,7 @@ func (p *Peer) SerializeUserMessage(msg *meowlib.UserMessage) ([]byte, error) {
// AsymEncryptMessage prepares a message to send to a specific peer contact
func (p *Peer) AsymEncryptMessage(Message []byte) (EncryptedMessage []byte, Signature []byte, Servers []*meowlib.Server, err error) {
EncryptedMessage, Signature, err = meowlib.AsymEncryptAndSign(p.Contact.EncryptionPublicKey, p.Me.Private, Message)
EncryptedMessage, Signature, err = meowlib.AsymEncryptAndSign(p.Contact.EncryptionPublicKey, p.MyIdentity.Private, Message)
if err != nil {
fmt.Println(err.Error())
return nil, nil, nil, err
@ -84,7 +134,7 @@ func (p *Peer) AsymEncryptMessage(Message []byte) (EncryptedMessage []byte, Sign
// AsymDecryptMessage reads a message from a specific peer contact
func (p *Peer) AsymDecryptMessage(Message []byte, Signature []byte) (DecryptedMessage []byte, err error) {
DecryptedMessage, err = meowlib.AsymDecryptAndCheck(p.Me.Private, p.Contact.ContactPublicKey, Message, Signature)
DecryptedMessage, err = meowlib.AsymDecryptAndCheck(p.MyIdentity.Private, p.Contact.ContactPublicKey, Message, Signature)
if err != nil {
fmt.Println(err.Error())
return nil, err