1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
use crate::account::AccountNumber;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use talpid_types::net::wireguard::PublicKey;
/// UUID for a device.
pub type DeviceId = String;
/// Human-readable device identifier.
pub type DeviceName = String;
/// Contains data for a device returned by the API.
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Device {
pub id: DeviceId,
pub name: DeviceName,
pub pubkey: PublicKey,
pub hijack_dns: bool,
pub created: DateTime<Utc>,
}
impl Device {
/// Return name with each word capitalized: "Happy Seagull" instead of "happy seagull"
pub fn pretty_name(&self) -> String {
self.name
.split_whitespace()
.map(|word| {
let mut chars = word.chars();
match chars.next() {
None => String::new(),
Some(c) => c.to_uppercase().chain(chars).collect(),
}
})
.collect::<Vec<String>>()
.join(" ")
}
pub fn eq_id(&self, other: &Device) -> bool {
self.id == other.id
}
}
/// Contains a device state.
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum DeviceState {
LoggedIn(AccountAndDevice),
LoggedOut,
Revoked,
}
impl DeviceState {
/// Returns the active account and device if the device is currently logged in to a valid
/// account.
pub fn logged_in(self) -> Option<AccountAndDevice> {
match self {
DeviceState::LoggedIn(client) => Some(client),
_ => None,
}
}
pub const fn is_logged_in(&self) -> bool {
matches!(self, Self::LoggedIn(_))
}
}
/// A [Device] and its associated account number.
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct AccountAndDevice {
#[serde(alias = "account_token")]
pub account_number: AccountNumber,
pub device: Device,
}
impl AccountAndDevice {
pub fn new(account_number: AccountNumber, device: Device) -> Self {
Self {
account_number,
device,
}
}
}
/// Reason why a [DeviceEvent] was emitted.
#[derive(Clone, Debug, Serialize)]
pub enum DeviceEventCause {
/// Logged in on a new device.
LoggedIn,
/// The device was removed due to user (or daemon) action.
LoggedOut,
/// Device was removed because it was not found remotely.
Revoked,
/// The device was updated, but not its key.
Updated,
/// The key was rotated.
RotatedKey,
}
/// Emitted when logging in or out of an account, or when the device changes.
#[derive(Clone, Debug, Serialize)]
pub struct DeviceEvent {
pub cause: DeviceEventCause,
pub new_state: DeviceState,
}
/// Emitted when a device is removed using the `RemoveDevice` RPC.
/// This is not sent by a normal logout or when it is revoked remotely.
#[derive(Clone, Debug, Serialize)]
pub struct RemoveDeviceEvent {
pub account_number: AccountNumber,
pub new_devices: Vec<Device>,
}
|