status-go/protocol/encryption/multidevice/multidevice.go

136 lines
3.9 KiB
Go

package multidevice
import (
"crypto/ecdsa"
"database/sql"
"github.com/google/uuid"
"github.com/status-im/status-go/eth-node/crypto"
)
type InstallationMetadata struct {
// The name of the device
Name string `json:"name"`
// The type of device
DeviceType string `json:"deviceType"`
// The FCMToken for mobile devices
FCMToken string `json:"fcmToken"`
}
type Installation struct {
// Identity is the string identity of the owner
Identity string `json:"identity"`
// The installation-id of the device
ID string `json:"id"`
// The last known protocol version of the device
Version uint32 `json:"version"`
// Enabled is whether the installation is enabled
Enabled bool `json:"enabled"`
// Timestamp is the last time we saw this device
Timestamp int64 `json:"timestamp"`
// InstallationMetadata
InstallationMetadata *InstallationMetadata `json:"metadata"`
}
func (i *Installation) UniqueKey() string {
return i.ID + i.Identity
}
type Config struct {
MaxInstallations int
ProtocolVersion uint32
InstallationID string
}
type Multidevice struct {
persistence *sqlitePersistence
config *Config
}
func New(db *sql.DB, config *Config) *Multidevice {
return &Multidevice{
config: config,
persistence: newSQLitePersistence(db),
}
}
func (s *Multidevice) InstallationID() string {
return s.config.InstallationID
}
func (s *Multidevice) GetActiveInstallations(identity *ecdsa.PublicKey) ([]*Installation, error) {
identityC := crypto.CompressPubkey(identity)
return s.persistence.GetActiveInstallations(s.config.MaxInstallations, identityC)
}
func (s *Multidevice) GetOurActiveInstallations(identity *ecdsa.PublicKey) ([]*Installation, error) {
identityC := crypto.CompressPubkey(identity)
installations, err := s.persistence.GetActiveInstallations(s.config.MaxInstallations-1, identityC)
if err != nil {
return nil, err
}
installations = append(installations, &Installation{
ID: s.config.InstallationID,
Version: s.config.ProtocolVersion,
})
return installations, nil
}
func (s *Multidevice) GetOurInstallations(identity *ecdsa.PublicKey) ([]*Installation, error) {
var found bool
identityC := crypto.CompressPubkey(identity)
installations, err := s.persistence.GetInstallations(identityC)
if err != nil {
return nil, err
}
for _, installation := range installations {
if installation.ID == s.config.InstallationID {
found = true
installation.Enabled = true
installation.Version = s.config.ProtocolVersion
}
}
if !found {
installations = append(installations, &Installation{
ID: s.config.InstallationID,
Enabled: true,
Version: s.config.ProtocolVersion,
})
}
return installations, nil
}
func (s *Multidevice) AddInstallations(identity []byte, timestamp int64, installations []*Installation, defaultEnabled bool) ([]*Installation, error) {
return s.persistence.AddInstallations(identity, timestamp, installations, defaultEnabled)
}
func (s *Multidevice) SetInstallationMetadata(identity *ecdsa.PublicKey, installationID string, metadata *InstallationMetadata) error {
identityC := crypto.CompressPubkey(identity)
return s.persistence.SetInstallationMetadata(identityC, installationID, metadata)
}
func (s *Multidevice) SetInstallationName(identity *ecdsa.PublicKey, installationID string, name string) error {
identityC := crypto.CompressPubkey(identity)
return s.persistence.SetInstallationName(identityC, installationID, name)
}
func (s *Multidevice) EnableInstallation(identity *ecdsa.PublicKey, installationID string) error {
identityC := crypto.CompressPubkey(identity)
return s.persistence.EnableInstallation(identityC, installationID)
}
func (s *Multidevice) DisableInstallation(myIdentityKey *ecdsa.PublicKey, installationID string) error {
myIdentityKeyC := crypto.CompressPubkey(myIdentityKey)
return s.persistence.DisableInstallation(myIdentityKeyC, installationID)
}
func GenerateInstallationID() string {
return uuid.New().String()
}