status-im/status-go

View on GitHub
protocol/encryption/multidevice/multidevice.go

Summary

Maintainability
A
0 mins
Test Coverage
A
91%
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()
}