mirror of
https://github.com/ddworken/hishtory.git
synced 2024-12-27 01:08:53 +01:00
7ebb693cdb
* Fix double-syncing error where devices receive entries from themselves * Fix incorrect error message * Add TODO * Update TestESubmitThenQuery after making query more efficient * Update TestDeletionRequests and remove unnecessary asserts * Swap server_test.go to using require * Fix incorrect require due to typo
129 lines
4.9 KiB
Go
129 lines
4.9 KiB
Go
package shared
|
|
|
|
import (
|
|
"database/sql/driver"
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
// Represents an encrypted history entry
|
|
type EncHistoryEntry struct {
|
|
EncryptedData []byte `json:"enc_data"`
|
|
Nonce []byte `json:"nonce"`
|
|
// DeviceId is the ID of the device that will read this entry from the backend. It is *not* the ID of the device that recorded the command.
|
|
DeviceId string `json:"device_id"`
|
|
UserId string `json:"user_id"`
|
|
// Note that EncHistoryEntry.Date == HistoryEntry.EndTime
|
|
Date time.Time `json:"time"`
|
|
// Note that EncHistoryEntry.EncryptedId == HistoryEntry.Id (for entries created after pre-saving support)
|
|
EncryptedId string `json:"encrypted_id"`
|
|
ReadCount int `json:"read_count"`
|
|
// Whether this encrypted history entry came from DeviceId. If IsFromSameDevice is true,
|
|
// then this won't be sent back by the query endpoint. We do still purposefully store
|
|
// these since they're useful for initializing new devices.
|
|
IsFromSameDevice bool `json:"is_from_same_device"`
|
|
}
|
|
|
|
// Represents a request to get all history entries from a given device. Used as part of bootstrapping
|
|
// a new device.
|
|
type DumpRequest struct {
|
|
UserId string `json:"user_id"`
|
|
RequestingDeviceId string `json:"requesting_device_id"`
|
|
RequestTime time.Time `json:"request_time"`
|
|
}
|
|
|
|
// Identifies where updates can be downloaded from
|
|
type UpdateInfo struct {
|
|
LinuxAmd64Url string `json:"linux_amd_64_url"`
|
|
LinuxAmd64AttestationUrl string `json:"linux_amd_64_attestation_url"`
|
|
LinuxArm64Url string `json:"linux_arm_64_url"`
|
|
LinuxArm64AttestationUrl string `json:"linux_arm_64_attestation_url"`
|
|
LinuxArm7Url string `json:"linux_arm_7_url"`
|
|
LinuxArm7AttestationUrl string `json:"linux_arm_7_attestation_url"`
|
|
DarwinAmd64Url string `json:"darwin_amd_64_url"`
|
|
DarwinAmd64UnsignedUrl string `json:"darwin_amd_64_unsigned_url"`
|
|
DarwinAmd64AttestationUrl string `json:"darwin_amd_64_attestation_url"`
|
|
DarwinArm64Url string `json:"darwin_arm_64_url"`
|
|
DarwinArm64UnsignedUrl string `json:"darwin_arm_64_unsigned_url"`
|
|
DarwinArm64AttestationUrl string `json:"darwin_arm_64_attestation_url"`
|
|
Version string `json:"version"`
|
|
}
|
|
|
|
// Represents a request to delete history entries
|
|
type DeletionRequest struct {
|
|
// The UserID that we're deleting entries for
|
|
UserId string `json:"user_id"`
|
|
// The DeviceID that is handling this deletion request. This struct is duplicated and put into the queue
|
|
// for each of a user's devices.
|
|
DestinationDeviceId string `json:"destination_device_id"`
|
|
// When this deletion request was sent
|
|
SendTime time.Time `json:"send_time"`
|
|
// The history entries to delete
|
|
Messages MessageIdentifiers `json:"messages"`
|
|
// How many times this request has been processed
|
|
ReadCount int `json:"read_count"`
|
|
}
|
|
|
|
// Identifies a list of history entries that should be deleted
|
|
type MessageIdentifiers struct {
|
|
Ids []MessageIdentifier `json:"message_ids"`
|
|
}
|
|
|
|
// Identifies a single history entry based on the device that recorded the entry, and additional metadata. Note that
|
|
// this does not include the command itself since that would risk including the sensitive data that is meant
|
|
// to be deleted
|
|
type MessageIdentifier struct {
|
|
// The device that the entry was recorded on (NOT the device where it is stored/requesting deletion)
|
|
DeviceId string `json:"device_id"`
|
|
// The timestamp when the command finished running. Serialized as "date" for legacy compatibility.
|
|
EndTime time.Time `json:"date"`
|
|
// The entry ID of the command.
|
|
// Note this field was added as part of supporting pre-saving commands, so older clients do not set this field
|
|
// And even for new clients, it may contain a per-device entry ID. For pre-saved entries, this is guaranteed to
|
|
// be present.
|
|
EntryId string `json:"entry_id"`
|
|
}
|
|
|
|
func (m *MessageIdentifiers) Scan(value any) error {
|
|
bytes, ok := value.([]byte)
|
|
if !ok {
|
|
return fmt.Errorf("failed to unmarshal JSONB value: %v", value)
|
|
}
|
|
|
|
result := MessageIdentifiers{}
|
|
err := json.Unmarshal(bytes, &result)
|
|
*m = result
|
|
return err
|
|
}
|
|
|
|
func (m MessageIdentifiers) Value() (driver.Value, error) {
|
|
return json.Marshal(m)
|
|
}
|
|
|
|
// Represents a piece of user feedback, submitted upon uninstall
|
|
type Feedback struct {
|
|
UserId string `json:"user_id" gorm:"not null"`
|
|
Date time.Time `json:"date" gorm:"not null"`
|
|
Feedback string `json:"feedback"`
|
|
}
|
|
|
|
// Response from submitting new history entries. Contains deletion requests and dump requests to avoid
|
|
// extra round-trip requests to the hishtory backend.
|
|
type SubmitResponse struct {
|
|
DumpRequests []*DumpRequest `json:"dump_requests"`
|
|
DeletionRequests []*DeletionRequest `json:"deletion_requests"`
|
|
}
|
|
|
|
func Chunks[k any](slice []k, chunkSize int) [][]k {
|
|
var chunks [][]k
|
|
for i := 0; i < len(slice); i += chunkSize {
|
|
end := i + chunkSize
|
|
if end > len(slice) {
|
|
end = len(slice)
|
|
}
|
|
chunks = append(chunks, slice[i:end])
|
|
}
|
|
return chunks
|
|
}
|