this repo has no description
1use super::super::{DeviceData, OAuthError}; 2use crate::types::Handle; 3use chrono::{DateTime, Utc}; 4use sqlx::PgPool; 5 6pub struct DeviceAccountRow { 7 pub did: String, 8 pub handle: Handle, 9 pub email: Option<String>, 10 pub last_used_at: DateTime<Utc>, 11} 12 13pub async fn create_device( 14 pool: &PgPool, 15 device_id: &str, 16 data: &DeviceData, 17) -> Result<(), OAuthError> { 18 sqlx::query!( 19 r#" 20 INSERT INTO oauth_device (id, session_id, user_agent, ip_address, last_seen_at) 21 VALUES ($1, $2, $3, $4, $5) 22 "#, 23 device_id, 24 data.session_id, 25 data.user_agent, 26 data.ip_address, 27 data.last_seen_at, 28 ) 29 .execute(pool) 30 .await?; 31 Ok(()) 32} 33 34pub async fn get_device(pool: &PgPool, device_id: &str) -> Result<Option<DeviceData>, OAuthError> { 35 let row = sqlx::query!( 36 r#" 37 SELECT session_id, user_agent, ip_address, last_seen_at 38 FROM oauth_device 39 WHERE id = $1 40 "#, 41 device_id 42 ) 43 .fetch_optional(pool) 44 .await?; 45 Ok(row.map(|r| DeviceData { 46 session_id: r.session_id, 47 user_agent: r.user_agent, 48 ip_address: r.ip_address, 49 last_seen_at: r.last_seen_at, 50 })) 51} 52 53pub async fn update_device_last_seen(pool: &PgPool, device_id: &str) -> Result<(), OAuthError> { 54 sqlx::query!( 55 r#" 56 UPDATE oauth_device 57 SET last_seen_at = NOW() 58 WHERE id = $1 59 "#, 60 device_id 61 ) 62 .execute(pool) 63 .await?; 64 Ok(()) 65} 66 67pub async fn delete_device(pool: &PgPool, device_id: &str) -> Result<(), OAuthError> { 68 sqlx::query!( 69 r#" 70 DELETE FROM oauth_device WHERE id = $1 71 "#, 72 device_id 73 ) 74 .execute(pool) 75 .await?; 76 Ok(()) 77} 78 79pub async fn upsert_account_device( 80 pool: &PgPool, 81 did: &str, 82 device_id: &str, 83) -> Result<(), OAuthError> { 84 sqlx::query!( 85 r#" 86 INSERT INTO oauth_account_device (did, device_id, created_at, updated_at) 87 VALUES ($1, $2, NOW(), NOW()) 88 ON CONFLICT (did, device_id) DO UPDATE SET updated_at = NOW() 89 "#, 90 did, 91 device_id 92 ) 93 .execute(pool) 94 .await?; 95 Ok(()) 96} 97 98pub async fn get_device_accounts( 99 pool: &PgPool, 100 device_id: &str, 101) -> Result<Vec<DeviceAccountRow>, OAuthError> { 102 let rows = sqlx::query!( 103 r#" 104 SELECT u.did, u.handle, u.email, ad.updated_at as last_used_at 105 FROM oauth_account_device ad 106 JOIN users u ON u.did = ad.did 107 WHERE ad.device_id = $1 108 AND u.deactivated_at IS NULL 109 AND u.takedown_ref IS NULL 110 ORDER BY ad.updated_at DESC 111 "#, 112 device_id 113 ) 114 .fetch_all(pool) 115 .await?; 116 Ok(rows 117 .into_iter() 118 .map(|r| DeviceAccountRow { 119 did: r.did, 120 handle: r.handle.into(), 121 email: r.email, 122 last_used_at: r.last_used_at, 123 }) 124 .collect()) 125} 126 127pub async fn verify_account_on_device( 128 pool: &PgPool, 129 device_id: &str, 130 did: &str, 131) -> Result<bool, OAuthError> { 132 let row = sqlx::query!( 133 r#" 134 SELECT 1 as exists 135 FROM oauth_account_device ad 136 JOIN users u ON u.did = ad.did 137 WHERE ad.device_id = $1 138 AND ad.did = $2 139 AND u.deactivated_at IS NULL 140 AND u.takedown_ref IS NULL 141 "#, 142 device_id, 143 did 144 ) 145 .fetch_optional(pool) 146 .await?; 147 Ok(row.is_some()) 148}