darkwing/server/dtos/entities/browser_profile_dto/
browser_profile.rsuse anyhow::Context;
use sqlx::prelude::FromRow;
use time::OffsetDateTime;
use crate::{
database::browser_profile::{
BrowserProfileWithFingerprint, Homepage, MainWebsite, Platform,
},
server::{dtos::settings_dto::SettingsList, error::AppResult},
};
use super::{
super::{proxy_dto::ProxyFullData, settings_dto::SettingsFullData},
Args, Canvas, CanvasJson, ClientRect, ClientRectJson, Cpu, CpuJson,
Geolocation, GeolocationJson, Locale, LocaleJson, MediaDevices, Memory,
MemoryJson, Ports, PortsJson, Screen, ScreenJson, Tabs, Timezone,
TimezoneJson, Useragent, UseragentJson, WebGL2Maximum, WebGPUInfo, Webgl,
WebglInfo, WebglInfoJson, WebglJson, Webrtc, WebrtcJson,
};
#[derive(Debug, Clone, FromRow)]
pub struct MiniBrowserProfile {
pub id: u64,
pub user_id: i64,
pub team_id: i64,
pub created_at: OffsetDateTime,
pub datadir_hash: Option<String>,
}
impl From<BrowserProfileWithFingerprint> for MiniBrowserProfile {
fn from(browser_profile: BrowserProfileWithFingerprint) -> Self {
Self {
id: browser_profile.id,
user_id: browser_profile.user_id,
team_id: browser_profile.team_id,
created_at: browser_profile.created_at,
datadir_hash: browser_profile.datadir_hash,
}
}
}
impl From<BrowserProfileFullData> for MiniBrowserProfile {
fn from(browser_profile: BrowserProfileFullData) -> Self {
Self {
id: browser_profile.id,
user_id: browser_profile.user_id,
team_id: browser_profile.team_id,
created_at: browser_profile.created_at,
datadir_hash: None,
}
}
}
#[derive(Debug, Clone)]
pub struct BrowserProfileFullData {
pub id: u64,
pub user_id: i64,
pub team_id: i64,
pub name: String,
pub main_website: MainWebsite,
pub platform: Platform,
pub useragent: Useragent,
pub webrtc: Webrtc,
pub canvas: Canvas,
pub webgl: Webgl,
pub webgl_info: WebglInfo,
pub client_rect: ClientRect,
pub timezone: Timezone,
pub locale: Locale,
pub geolocation: Geolocation,
pub do_not_track: bool,
pub args: Args,
pub cpu: Cpu,
pub memory: Memory,
pub screen: Screen,
pub ports: Ports,
pub tabs: Tabs,
pub cpu_architecture: String,
pub os_version: String,
pub connection_downlink: f64,
pub connection_effective_type: String,
pub connection_rtt: u32,
pub connection_save_data: bool,
pub vendor_sub: String,
pub product_sub: String,
pub vendor: String,
pub product: String,
pub app_code_name: String,
pub media_devices: MediaDevices,
pub datadir_hash: Option<String>,
pub platform_version: String,
pub webgl2_maximum: Option<WebGL2Maximum>,
pub login: Option<String>,
pub password: Option<String>,
pub is_hidden_profile_name: bool,
pub webgpu: WebGPUInfo,
pub settings: SettingsList,
pub proxy: Option<ProxyFullData>,
pub created_at: OffsetDateTime,
pub homepages: Vec<Homepage>,
}
impl BrowserProfileFullData {
pub async fn new(
browser_profile_fingerprint: BrowserProfileWithFingerprint,
settings: Vec<SettingsFullData>,
proxy: Option<ProxyFullData>,
homepages: Vec<Homepage>,
) -> AppResult<Self> {
let useragent: UseragentJson =
serde_json::from_str(&browser_profile_fingerprint.useragent)
.context("Failed to parse useragent")?;
let useragent = Useragent::try_from(useragent)?;
let screen: ScreenJson =
serde_json::from_str(&browser_profile_fingerprint.screen)
.context("Failed to parse screen")?;
let screen = Screen::try_from(screen)?;
let client_rect: ClientRectJson =
serde_json::from_str(&browser_profile_fingerprint.client_rect)
.context("Failed to parse client rect")?;
let client_rect = ClientRect::try_from(client_rect)?;
let webrtc: WebrtcJson =
serde_json::from_str(&browser_profile_fingerprint.webrtc)
.context("Failed to parse webrtc")?;
let webrtc = Webrtc::try_from(webrtc)?;
let canvas: CanvasJson =
serde_json::from_str(&browser_profile_fingerprint.canvas)
.context("Failed to parse canvas")?;
let canvas = Canvas::try_from(canvas)?;
let webgl: WebglJson =
serde_json::from_str(&browser_profile_fingerprint.webgl)
.context("Failed to parse webgl")?;
let webgl = Webgl::try_from(webgl)?;
let webgl_info: WebglInfoJson =
serde_json::from_str(&browser_profile_fingerprint.webgl_info)
.context("Failed to parse webgl_info")?;
let webgl2_maximum = match webgl_info.webgl2_maximum {
Some(ref webgl2_maximum) => serde_json::from_str(webgl2_maximum)
.context("Failed to parse webgl2_maximum")?,
None => None,
};
let webgl_info = WebglInfo::try_from(webgl_info)?;
let ports: PortsJson =
serde_json::from_str(&browser_profile_fingerprint.ports)
.context("Failed to parse ports")?;
let ports = Ports::try_from(ports)?;
let media_devices =
MediaDevices::try_from(browser_profile_fingerprint.media_devices)?;
let do_not_track = browser_profile_fingerprint.do_not_track == 1;
let connection_save_data =
browser_profile_fingerprint.connection_save_data == 1;
let cpu: CpuJson = serde_json::from_str(&browser_profile_fingerprint.cpu)
.context("Failed to parse cpu")?;
let cpu = Cpu::try_from(cpu)?;
let memory: MemoryJson =
serde_json::from_str(&browser_profile_fingerprint.memory)
.context("Failed to parse memory")?;
let memory = Memory::try_from(memory)?;
let args = Args::from_json_str(&browser_profile_fingerprint.args)
.context("Failed to parse args")?;
let geolocation: GeolocationJson =
serde_json::from_str(&browser_profile_fingerprint.geolocation)
.context("Failed to parse geolocation")?;
let geolocation = Geolocation::try_from(geolocation)?;
let timezone: TimezoneJson =
serde_json::from_str(&browser_profile_fingerprint.timezone)
.context("Failed to parse timezone")?;
let timezone = Timezone::try_from(timezone)?;
let locale: LocaleJson =
serde_json::from_str(&browser_profile_fingerprint.locale)
.context("Failed to parse locale")?;
let locale = Locale::try_from(locale)?;
let tabs_from_browser_profile_table: Result<Tabs, serde_json::Error> =
serde_json::from_str(&browser_profile_fingerprint.tabs);
let tabs_from_special_table: Result<Tabs, serde_json::Error> =
serde_json::from_str(
&browser_profile_fingerprint
.browser_profile_tabs
.unwrap_or("".to_string()),
);
let tabs = tabs_from_special_table
.unwrap_or(tabs_from_browser_profile_table.unwrap_or(Tabs(vec![])));
let webgpu = WebGPUInfo::try_from(browser_profile_fingerprint.webgpu)
.context("Failed to parse webgpu (new)")?;
let main_website =
MainWebsite::from(browser_profile_fingerprint.main_website);
let settings = SettingsList::new(settings);
Ok(Self {
id: browser_profile_fingerprint.id,
user_id: browser_profile_fingerprint.user_id,
team_id: browser_profile_fingerprint.team_id,
name: browser_profile_fingerprint.name,
main_website,
platform: Platform::from(browser_profile_fingerprint.platform),
useragent,
webrtc,
canvas,
webgl,
webgl_info,
client_rect,
timezone,
locale,
geolocation,
do_not_track,
args,
cpu,
memory,
screen,
ports,
tabs,
cpu_architecture: browser_profile_fingerprint.cpu_architecture,
os_version: browser_profile_fingerprint.os_version,
connection_downlink: browser_profile_fingerprint.connection_downlink,
connection_effective_type: browser_profile_fingerprint
.connection_effective_type,
connection_rtt: browser_profile_fingerprint.connection_rtt,
connection_save_data,
vendor_sub: browser_profile_fingerprint.vendor_sub,
product_sub: browser_profile_fingerprint.product_sub,
vendor: browser_profile_fingerprint.vendor,
product: browser_profile_fingerprint.product,
app_code_name: browser_profile_fingerprint.app_code_name,
media_devices,
datadir_hash: browser_profile_fingerprint.datadir_hash,
platform_version: browser_profile_fingerprint.platform_version,
webgl2_maximum,
is_hidden_profile_name: browser_profile_fingerprint
.is_hidden_profile_name
.unwrap_or(false),
login: browser_profile_fingerprint.login,
password: browser_profile_fingerprint.password,
webgpu,
settings,
proxy,
created_at: browser_profile_fingerprint.created_at,
homepages,
})
}
}