@ -9,7 +9,6 @@ use rocket::{
response ::{ status , Content , Flash , Redirect } ,
} ;
use rocket_i18n ::I18n ;
use serde_json ;
use std ::{ borrow ::Cow , collections ::HashMap } ;
use validator ::{ Validate , ValidationError , ValidationErrors } ;
@ -42,7 +41,7 @@ pub fn me(user: Option<User>) -> RespondOrRedirect {
}
#[ get( " /@/<name> " , rank = 2) ]
pub fn details (
pub async fn details (
name : String ,
rockets : PlumeRocket ,
fetch_rockets : PlumeRocket ,
@ -50,7 +49,7 @@ pub fn details(
update_conn : DbConn ,
) -> Result < Ructe , ErrorPage > {
let conn = & * rockets . conn ;
let user = User ::find_by_fqn ( & rockets , & name ) ? ;
let user = User ::find_by_fqn ( & rockets , & name ) . await ? ;
let recents = Post ::get_recents_for_author ( & * conn , & user , 6 ) ? ;
let reshares = Reshare ::get_recents_for_author ( & * conn , & user , 6 ) ? ;
let worker = & rockets . worker ;
@ -61,6 +60,7 @@ pub fn details(
worker . execute ( move | | {
for create_act in user_clone
. fetch_outbox ::< Create > ( )
. await
. expect ( "Remote user: outbox couldn't be fetched" )
{
match create_act . create_props . object_object ::< LicensedArticle > ( ) {
@ -79,6 +79,7 @@ pub fn details(
worker . execute ( move | | {
for user_id in user_clone
. fetch_followers_ids ( )
. await
. expect ( "Remote user: fetching followers error" )
{
let follower = User ::from_id ( & fetch_followers_rockets , & user_id , None )
@ -101,6 +102,7 @@ pub fn details(
worker . execute ( move | | {
user_clone
. refetch ( & * update_conn )
. await
. expect ( "Couldn't update user info" ) ;
} ) ;
}
@ -146,13 +148,13 @@ pub fn dashboard_auth(i18n: I18n) -> Flash<Redirect> {
}
#[ post( " /@/<name>/follow " ) ]
pub fn follow (
pub async fn follow (
name : String ,
user : User ,
rockets : PlumeRocket ,
) -> Result < Flash < Redirect > , ErrorPage > {
let conn = & * rockets . conn ;
let target = User ::find_by_fqn ( & rockets , & name ) ? ;
let target = User ::find_by_fqn ( & rockets , & name ) . await ? ;
let message = if let Ok ( follow ) = follows ::Follow ::find ( & * conn , user . id , target . id ) {
let delete_act = follow . build_undo ( & * conn ) ? ;
local_inbox (
@ -190,26 +192,26 @@ pub fn follow(
}
#[ post( " /@/<name>/follow " , data = " <remote_form> " , rank = 2) ]
pub fn follow_not_connected (
pub async fn follow_not_connected (
rockets : PlumeRocket ,
name : String ,
remote_form : Option < LenientForm < RemoteForm > > ,
i18n : I18n ,
) -> Result < RespondOrRedirect , ErrorPage > {
let target = User ::find_by_fqn ( & rockets , & name ) ? ;
let target = User ::find_by_fqn ( & rockets , & name ) . await ? ;
if let Some ( remote_form ) = remote_form {
if let Some ( uri ) = User ::fetch_remote_interact_uri ( & remote_form )
. await
. ok ( )
. and_then ( | uri | {
rt_format ! (
uri ,
uri = format! (
Some ( uri . replace (
"{uri}" ,
& format! (
"{}@{}" ,
target . fqn ,
target . get_instance ( & rockets . conn ) . ok ( ) ? . public_domain
)
)
. ok ( )
) ,
) )
} )
{
Ok ( Redirect ::to ( uri ) . into ( ) )
@ -266,15 +268,18 @@ pub fn follow_auth(name: String, i18n: I18n) -> Flash<Redirect> {
}
#[ get( " /@/<name>/followers?<page> " , rank = 2) ]
pub fn followers (
pub async fn followers (
name : String ,
page : Option < Page > ,
rockets : PlumeRocket ,
) -> Result < Ructe , ErrorPage > {
let conn = & * rockets . conn ;
let page = page . unwrap_or_default ( ) ;
let user = User ::find_by_fqn ( & rockets , & name ) ? ;
let followers_count = user . count_followers ( & * conn ) ? ;
let user : User = User ::find_by_fqn ( & rockets , & name ) . await ? ;
let followers_count = match user . count_followers ( & conn ) {
Ok ( num ) = > num ,
Err ( _ ) = > 0 ,
} ;
Ok ( render ! ( users ::followers (
& rockets . to_context ( ) ,
@ -293,14 +298,14 @@ pub fn followers(
}
#[ get( " /@/<name>/followed?<page> " , rank = 2) ]
pub fn followed (
pub async fn followed (
name : String ,
page : Option < Page > ,
rockets : PlumeRocket ,
) -> Result < Ructe , ErrorPage > {
let conn = & * rockets . conn ;
let page = page . unwrap_or_default ( ) ;
let user = User ::find_by_fqn ( & rockets , & name ) ? ;
let user = User ::find_by_fqn ( & rockets , & name ) . await ? ;
let followed_count = user . count_followed ( conn ) ? ;
Ok ( render ! ( users ::followed (
@ -320,12 +325,12 @@ pub fn followed(
}
#[ get( " /@/<name> " , rank = 1) ]
pub fn activity_details (
pub async fn activity_details (
name : String ,
rockets : PlumeRocket ,
_ap : ApRequest ,
) -> Option < ActivityStream < CustomPerson > > {
let user = User ::find_by_fqn ( & rockets , & name ) . ok ( ) ? ;
let user : User = User ::find_by_fqn ( & rockets , & name ) . await ? ;
Some ( ActivityStream ::new ( user . to_activity ( & * rockets . conn ) . ok ( ) ? ) )
}
@ -412,50 +417,49 @@ pub fn update(
}
#[ post( " /@/<name>/delete " ) ]
pub fn delete (
pub async fn delete (
name : String ,
user : User ,
mut cookies : Cookies < ' _ > ,
rockets : PlumeRocket ,
) -> Result < Flash < Redirect > , ErrorPage > {
let account = User ::find_by_fqn ( & rockets , & name ) ? ;
if user . id = = account . id {
account . delete ( & * rockets . conn , & rockets . searcher ) ? ;
let target = User ::one_by_instance ( & * rockets . conn ) ? ;
let delete_act = account . delete_activity ( & * rockets . conn ) ? ;
rockets
. worker
. execute ( move | | broadcast ( & account , delete_act , target ) ) ;
if let Some ( cookie ) = cookies . get_private ( AUTH_COOKIE ) {
cookies . remove_private ( cookie ) ;
}
Ok ( Flash ::success (
Redirect ::to ( uri ! ( super ::instance ::index ) ) ,
i18n ! ( rockets . intl . catalog , "Your account has been deleted." ) ,
) )
} else {
Ok ( Flash ::error (
let account = User ::find_by_fqn ( & rockets , & name ) . await ? ;
if user . id ! = account . id {
return Ok ( Flash ::error (
Redirect ::to ( uri ! ( edit : name = name ) ) ,
i18n ! (
rockets . intl . catalog ,
"You can't delete someone else's account."
) ,
) )
) ) ;
}
account . delete ( & * rockets . conn , & rockets . searcher ) ? ;
let target = User ::one_by_instance ( & * rockets . conn ) ? ;
let delete_act = account . delete_activity ( & * rockets . conn ) ? ;
rockets
. worker
. execute ( move | | broadcast ( & account , delete_act , target ) ) ;
if let Some ( cookie ) = cookies . get_private ( AUTH_COOKIE ) {
cookies . remove_private ( cookie ) ;
}
Ok ( Flash ::success (
Redirect ::to ( uri ! ( super ::instance ::index ) ) ,
i18n ! ( rockets . intl . catalog , "Your account has been deleted." ) ,
) )
}
#[ derive(Default, FromForm, Validate) ]
#[ validate(schema(
function = "passwords_match" ,
skip_on_field_errors = "false" ,
skip_on_field_errors = false ,
message = "Passwords are not matching"
) ) ]
pub struct NewUserForm {
#[ validate(
length ( min = "1" , message = "Username can't be empty" ) ,
length ( min = 1 , message = "Username can't be empty" ) ,
custom (
function = "validate_username" ,
message = "User name is not allowed to contain any of < > & @ ' or \""
@ -464,9 +468,9 @@ pub struct NewUserForm {
pub username : String ,
#[ validate(email(message = " Invalid email " )) ]
pub email : String ,
#[ validate(length(min = " 8" , message = " Password should be at least 8 characters long " )) ]
#[ validate(length(min = 8, message = " Password should be at least 8 characters long " )) ]
pub password : String ,
#[ validate(length(min = " 8" , message = " Password should be at least 8 characters long " )) ]
#[ validate(length(min = 8, message = " Password should be at least 8 characters long " )) ]
pub password_confirmation : String ,
}
@ -565,37 +569,44 @@ pub fn create(
}
#[ get( " /@/<name>/outbox " ) ]
pub fn outbox ( name : String , rockets : PlumeRocket ) -> Option < ActivityStream < OrderedCollection > > {
let user = User ::find_by_fqn ( & rockets , & name ) . ok ( ) ? ;
pub async fn outbox (
name : String ,
rockets : PlumeRocket ,
) -> Option < ActivityStream < OrderedCollection > > {
let user = User ::find_by_fqn ( & rockets , & name ) . await . ok ( ) ? ;
user . outbox ( & * rockets . conn ) . ok ( )
}
#[ get( " /@/<name>/outbox?<page> " ) ]
pub fn outbox_page (
pub async fn outbox_page (
name : String ,
page : Page ,
rockets : PlumeRocket ,
) -> Option < ActivityStream < OrderedCollectionPage > > {
let user = User ::find_by_fqn ( & rockets , & name ) . ok ( ) ? ;
let user = User ::find_by_fqn ( & rockets , & name ) . await . ok ( ) ? ;
user . outbox_page ( & * rockets . conn , page . limits ( ) ) . ok ( )
}
#[ post( " /@/<name>/inbox " , data = " <data> " ) ]
pub fn inbox (
pub async fn inbox (
name : String ,
data : inbox ::SignedJson < serde_json ::Value > ,
headers : Headers < ' _ > ,
rockets : PlumeRocket ,
) -> Result < String , status ::BadRequest < & ' static str > > {
User ::find_by_fqn ( & rockets , & name ) . map_err ( | _ | status ::BadRequest ( Some ( "User not found" ) ) ) ? ;
inbox ::handle_incoming ( rockets , data , headers )
User ::find_by_fqn ( & rockets , & name )
. await
. map_err ( | _ | status ::BadRequest ( Some ( "User not found" ) ) ) ? ;
inbox ::handle_incoming ( rockets , data , headers ) . await
}
#[ get( " /@/<name>/followers " , rank = 1) ]
pub fn ap_followers (
pub async fn ap_followers (
name : String ,
rockets : PlumeRocket ,
_ap : ApRequest ,
) -> Option < ActivityStream < OrderedCollection > > {
let user = User ::find_by_fqn ( & rockets , & name ) . ok ( ) ? ;
let user = User ::find_by_fqn ( & rockets , & name ) . await ? ;
let followers = user
. get_followers ( & * rockets . conn )
. ok ( ) ?
@ -615,9 +626,9 @@ pub fn ap_followers(
}
#[ get( " /@/<name>/atom.xml " ) ]
pub fn atom_feed ( name : String , rockets : PlumeRocket ) -> Option < Content < String > > {
pub async fn atom_feed ( name : String , rockets : PlumeRocket ) -> Option < Content < String > > {
let conn = & * rockets . conn ;
let author = User ::find_by_fqn ( & rockets , & name ) . ok ( ) ? ;
let author = User ::find_by_fqn ( & rockets , & name ) . await ? ;
let entries = Post ::get_recents_for_author ( conn , & author , 15 ) . ok ( ) ? ;
let uri = Instance ::get_local ( )
. ok ( ) ?