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