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