Re-write email backend, use SMTP directly.

This commit is contained in:
Paul Makles
2020-08-30 17:16:53 +01:00
parent ff0e539c7b
commit cbac802978
21 changed files with 354 additions and 303 deletions

View File

@@ -1,12 +1,11 @@
use super::Response;
use crate::database;
use crate::email;
use crate::util::gen_token;
use crate::util::captcha;
use crate::util::{captcha, email, gen_token};
use bcrypt::{hash, verify};
use chrono::prelude::*;
use database::user::User;
use log::error;
use mongodb::bson::{doc, from_bson, Bson};
use rocket_contrib::json::Json;
use serde::{Deserialize, Serialize};
@@ -31,15 +30,11 @@ pub struct Create {
#[post("/create", data = "<info>")]
pub fn create(info: Json<Create>) -> Response {
if let Err(error) = captcha::verify(&info.captcha) {
return Response::BadRequest(
json!({ "error": error })
);
return Response::BadRequest(json!({ "error": error }));
}
if true {
return Response::BadRequest(
json!({ "error": "Registration disabled." })
);
return Response::BadRequest(json!({ "error": "Registration disabled." }));
}
let col = database::get_collection("users");
@@ -152,7 +147,9 @@ pub fn verify_email(code: String) -> Response {
)
.expect("Failed to update user!");
email::send_welcome_email(target.to_string(), user.username);
if let Err(err) = email::send_welcome_email(target.to_string(), user.username) {
error!("Failed to send welcome email! {}", err);
}
Response::Redirect(super::Redirect::to("https://app.revolt.chat"))
}
@@ -174,9 +171,7 @@ pub struct Resend {
#[post("/resend", data = "<info>")]
pub fn resend_email(info: Json<Resend>) -> Response {
if let Err(error) = captcha::verify(&info.captcha) {
return Response::BadRequest(
json!({ "error": error })
);
return Response::BadRequest(json!({ "error": error }));
}
let col = database::get_collection("users");
@@ -223,12 +218,11 @@ pub fn resend_email(info: Json<Resend>) -> Response {
None,
).expect("Failed to update user!");
match email::send_verification_email(info.email.to_string(), code) {
true => Response::Result(super::Status::Ok),
false => Response::InternalServerError(
json!({ "error": "Failed to send email! Likely an issue with the backend API." }),
),
if let Err(err) = email::send_verification_email(info.email.clone(), code) {
return Response::InternalServerError(json!({ "error": err }));
}
Response::Result(super::Status::Ok)
}
} else {
Response::NotFound(json!({ "error": "Email not found or pending verification!" }))
@@ -249,9 +243,7 @@ pub struct Login {
#[post("/login", data = "<info>")]
pub fn login(info: Json<Login>) -> Response {
if let Err(error) = captcha::verify(&info.captcha) {
return Response::BadRequest(
json!({ "error": error })
);
return Response::BadRequest(json!({ "error": error }));
}
let col = database::get_collection("users");

View File

@@ -1,7 +1,7 @@
use super::Response;
use crate::database::{
self, channel::Channel, get_relationship, get_relationship_internal, message::Message,
Permission, PermissionCalculator, Relationship, user::User
user::User, Permission, PermissionCalculator, Relationship,
};
use crate::notifications::{
self,
@@ -506,11 +506,7 @@ pub struct SendMessage {
/// send a message to a channel
#[post("/<target>/messages", data = "<message>")]
pub fn send_message(
user: User,
target: Channel,
message: Json<SendMessage>,
) -> Option<Response> {
pub fn send_message(user: User, target: Channel, message: Json<SendMessage>) -> Option<Response> {
let permissions = with_permissions!(user, target);
if !permissions.get_send_messages() {
@@ -657,10 +653,8 @@ pub fn edit_message(
pub fn delete_message(user: User, target: Channel, message: Message) -> Option<Response> {
let permissions = with_permissions!(user, target);
if !permissions.get_manage_messages() {
if message.author != user.id {
return Some(Response::LackingPermission(Permission::ManageMessages));
}
if !permissions.get_manage_messages() && message.author != user.id {
return Some(Response::LackingPermission(Permission::ManageMessages));
}
let col = database::get_collection("messages");

View File

@@ -2,7 +2,8 @@ use super::channel::ChannelType;
use super::Response;
use crate::database::guild::{fetch_member as get_member, get_invite, Guild, MemberKey};
use crate::database::{
self, channel::fetch_channel, guild::serialise_guilds_with_channels, channel::Channel, Permission, PermissionCalculator, user::User
self, channel::fetch_channel, channel::Channel, guild::serialise_guilds_with_channels,
user::User, Permission, PermissionCalculator,
};
use crate::notifications::{
self,
@@ -51,11 +52,13 @@ pub fn my_guilds(user: User) -> Response {
#[get("/<target>")]
pub fn guild(user: User, target: Guild) -> Option<Response> {
with_permissions!(user, target);
if let Ok(result) = target.seralise_with_channels() {
Some(Response::Success(result))
} else {
Some(Response::InternalServerError(json!({ "error": "Failed to fetch channels!" })))
Some(Response::InternalServerError(
json!({ "error": "Failed to fetch channels!" }),
))
}
}
@@ -153,33 +156,31 @@ pub fn remove_guild(user: User, target: Guild) -> Option<Response> {
json!({ "error": "Could not fetch channels." }),
))
}
} else {
if database::get_collection("members")
.delete_one(
doc! {
"_id.guild": &target.id,
"_id.user": &user.id,
},
None,
)
.is_ok()
{
notifications::send_message_threaded(
None,
target.id.clone(),
Notification::guild_user_leave(UserLeave {
id: target.id.clone(),
user: user.id.clone(),
banned: false,
}),
);
} else if database::get_collection("members")
.delete_one(
doc! {
"_id.guild": &target.id,
"_id.user": &user.id,
},
None,
)
.is_ok()
{
notifications::send_message_threaded(
None,
target.id.clone(),
Notification::guild_user_leave(UserLeave {
id: target.id.clone(),
user: user.id.clone(),
banned: false,
}),
);
Some(Response::Result(super::Status::Ok))
} else {
Some(Response::InternalServerError(
json!({ "error": "Failed to remove you from the guild." }),
))
}
Some(Response::Result(super::Status::Ok))
} else {
Some(Response::InternalServerError(
json!({ "error": "Failed to remove you from the guild." }),
))
}
}
@@ -243,7 +244,7 @@ pub fn create_channel(user: User, target: Guild, info: Json<CreateChannel>) -> O
"channels": &id
}
},
None
None,
)
.is_ok()
{
@@ -326,10 +327,8 @@ pub fn remove_invite(user: User, target: Guild, code: String) -> Option<Response
let (permissions, _) = with_permissions!(user, target);
if let Some((guild_id, _, invite)) = get_invite(&code, None) {
if invite.creator != user.id {
if !permissions.get_manage_server() {
return Some(Response::LackingPermission(Permission::ManageServer));
}
if invite.creator != user.id && !permissions.get_manage_server() {
return Some(Response::LackingPermission(Permission::ManageServer));
}
if database::get_collection("guilds")
@@ -621,14 +620,16 @@ pub fn kick_member(user: User, target: Guild, other: String) -> Option<Response>
return Some(Response::LackingPermission(Permission::KickMembers));
}
if let Ok(result) = get_member(MemberKey( target.id.clone(), other.clone() )) {
if let Ok(result) = get_member(MemberKey(target.id.clone(), other.clone())) {
if result.is_none() {
return Some(Response::BadRequest(
json!({ "error": "User not part of guild." }),
));
}
} else {
return Some(Response::InternalServerError(json!({ "error": "Failed to fetch member." })))
return Some(Response::InternalServerError(
json!({ "error": "Failed to fetch member." }),
));
}
if database::get_collection("members")
@@ -691,14 +692,16 @@ pub fn ban_member(
return Some(Response::LackingPermission(Permission::BanMembers));
}
if let Ok(result) = get_member(MemberKey( target.id.clone(), other.clone() )) {
if let Ok(result) = get_member(MemberKey(target.id.clone(), other.clone())) {
if result.is_none() {
return Some(Response::BadRequest(
json!({ "error": "User not part of guild." }),
));
}
} else {
return Some(Response::InternalServerError(json!({ "error": "Failed to fetch member." })))
return Some(Response::InternalServerError(
json!({ "error": "Failed to fetch member." }),
));
}
if database::get_collection("guilds")

View File

@@ -1,7 +1,7 @@
use super::Response;
use crate::util::variables::{USE_EMAIL_VERIFICATION, USE_HCAPTCHA};
use mongodb::bson::doc;
use std::env;
/// root
#[get("/")]
@@ -14,7 +14,8 @@ pub fn root() -> Response {
"patch": 9
},
"features": {
"captcha": env::var("HCAPTCHA_KEY").is_ok()
"email_verification": USE_EMAIL_VERIFICATION.clone(),
"captcha": USE_HCAPTCHA.clone(),
}
}))
}

View File

@@ -1,5 +1,7 @@
use super::Response;
use crate::database::{self, get_relationship, get_relationship_internal, mutual, Relationship, user::User};
use crate::database::{
self, get_relationship, get_relationship_internal, user::User, Relationship,
};
use crate::notifications::{
self,
events::{users::*, Notification},
@@ -15,18 +17,14 @@ use ulid::Ulid;
/// retrieve your user information
#[get("/@me")]
pub fn me(user: User) -> Response {
Response::Success(
user.serialise(Relationship::SELF as i32)
)
Response::Success(user.serialise(Relationship::SELF as i32))
}
/// retrieve another user's information
#[get("/<target>")]
pub fn user(user: User, target: User) -> Response {
let relationship = get_relationship(&user, &target) as i32;
Response::Success(
user.serialise(relationship)
)
Response::Success(user.serialise(relationship))
}
#[derive(Serialize, Deserialize)]