11use crate :: AppState ;
22use axum:: extract:: { Path , State } ;
3- use axum:: routing:: post;
3+ use axum:: routing:: { delete , post} ;
44use axum:: { Extension , Json } ;
55use serde:: { Deserialize , Serialize } ;
66use std:: sync:: Arc ;
7+ use lambda_http:: tracing:: info;
78use serde_json:: json;
89use twilight_model:: id:: marker:: UserMarker ;
910use twilight_model:: id:: Id ;
@@ -12,14 +13,16 @@ use crate::users::models::{Link, User};
1213pub fn router ( ) -> axum:: Router < AppState > {
1314 axum:: Router :: new ( )
1415 . route ( "/" , post ( post_link) )
16+ . route ( "/{link_address}" , delete ( delete_link) )
1517}
1618
1719#[ derive( Clone , Serialize , Deserialize ) ]
20+ #[ serde( rename_all = "lowercase" ) ]
1821enum LinkOrigin {
19- MICROSOFT ,
20- GOOGLE ,
21- EMAIL ,
22- DISCORD ,
22+ Microsoft ,
23+ Google ,
24+ Email ,
25+ Discord ,
2326}
2427
2528#[ derive( Clone , Serialize , Deserialize ) ]
@@ -39,25 +42,25 @@ async fn post_link(
3942 }
4043 let email;
4144 match link_req. origin {
42- LinkOrigin :: DISCORD => {
45+ LinkOrigin :: Discord => {
4346 // Handle Discord linking logic here
4447 email = discord_user. current_user ( ) . await . map_err ( |_| http:: StatusCode :: UNAUTHORIZED ) ?
4548 . model ( ) . await . map_err ( |_| http:: StatusCode :: UNAUTHORIZED ) ?. email . unwrap ( ) ;
4649 } ,
47- LinkOrigin :: MICROSOFT => {
50+ LinkOrigin :: Microsoft => {
4851 // Handle Microsoft linking logic here
4952 email = oidc_email ( "https://graph.microsoft.com/oidc/userinfo" , link_req. token , & app_state) . await ?;
5053 } ,
51- LinkOrigin :: GOOGLE => {
54+ LinkOrigin :: Google => {
5255 // Handle Google linking logic here
5356 email = oidc_email ( "https://openidconnect.googleapis.com/v1/userinfo" , link_req. token , & app_state) . await ?;
5457 } ,
55- LinkOrigin :: EMAIL => {
58+ LinkOrigin :: Email => {
5659 todo ! ( ) ;
5760 } ,
5861 }
5962
60- let new_link = Link { link_address : email, linked_at : chrono:: Utc :: now ( ) . timestamp_millis ( ) as u64 } ;
63+ let new_link = Link { link_address : email, linked_at : chrono:: Utc :: now ( ) . timestamp_millis ( ) as u64 , active : true } ;
6164 let json_resp = Json ( json ! ( new_link) ) ;
6265 let mut user_model = User :: from_db ( & user_id. to_string ( ) , & app_state. dynamo ) . await . unwrap ( ) ;
6366 user_model. links . retain ( |l| l. link_address != new_link. link_address ) ;
@@ -89,3 +92,26 @@ async fn oidc_email(
8992 Err ( _) => Err ( http:: StatusCode :: INTERNAL_SERVER_ERROR ) ,
9093 }
9194}
95+
96+ async fn delete_link (
97+ Path ( ( user_id, link_address) ) : Path < ( Id < UserMarker > , String ) > ,
98+ Extension ( discord_user) : Extension < Arc < twilight_http:: Client > > ,
99+ State ( app_state) : State < AppState >
100+ ) -> Result < Json < serde_json:: Value > , http:: StatusCode > {
101+ if user_id != discord_user. current_user ( ) . await . unwrap ( ) . model ( ) . await . unwrap ( ) . id {
102+ return Err ( http:: StatusCode :: NOT_FOUND ) ;
103+ }
104+
105+ let mut user_model = User :: from_db ( & user_id. to_string ( ) , & app_state. dynamo ) . await . unwrap ( ) ;
106+ let existing_link = user_model. links . pop_if ( |l| l. link_address == link_address) ;
107+ info ! ( "Deleting link for user {}: {}" , user_id, link_address) ;
108+ if existing_link. is_none ( ) {
109+ return Err ( http:: StatusCode :: NOT_FOUND ) ;
110+ }
111+ let mut existing_link = existing_link. unwrap ( ) ;
112+ existing_link. active = false ;
113+ user_model. links . push ( existing_link) ;
114+ user_model. save ( & app_state. dynamo ) . await ;
115+
116+ Ok ( Json ( json ! ( { "status" : "success" , "message" : "Link deleted" } ) ) )
117+ }
0 commit comments