aboutsummaryrefslogtreecommitdiffstats
path: root/atuin-server/src/handlers
diff options
context:
space:
mode:
authorEllie Huxtable <ellie@elliehuxtable.com>2023-03-07 22:09:19 +0000
committerGitHub <noreply@github.com>2023-03-07 22:09:19 +0000
commitb978f9a4de662270a7874d16315f6827e58c2b0b (patch)
tree6668af01e951e31cd4320b1b2985d4506cbbdc3b /atuin-server/src/handlers
parentfix(client): always read session_path from settings (#757) (diff)
downloadatuin-b978f9a4de662270a7874d16315f6827e58c2b0b.zip
Add register notification webhook (#764)
I find it super motivating when people use my stuff, so this makes it _even easier_ to know when someone new signs up!
Diffstat (limited to 'atuin-server/src/handlers')
-rw-r--r--atuin-server/src/handlers/user.rs44
1 files changed, 41 insertions, 3 deletions
diff --git a/atuin-server/src/handlers/user.rs b/atuin-server/src/handlers/user.rs
index 9e145d3c..61af989c 100644
--- a/atuin-server/src/handlers/user.rs
+++ b/atuin-server/src/handlers/user.rs
@@ -1,4 +1,6 @@
use std::borrow::Borrow;
+use std::collections::HashMap;
+use std::time::Duration;
use axum::{
extract::{Path, State},
@@ -6,7 +8,7 @@ use axum::{
};
use http::StatusCode;
use sodiumoxide::crypto::pwhash::argon2id13;
-use tracing::{debug, error, instrument};
+use tracing::{debug, error, info, instrument};
use uuid::Uuid;
use super::{ErrorResponse, ErrorResponseStatus, RespExt};
@@ -16,6 +18,8 @@ use crate::{
router::AppState,
};
+use reqwest::header::CONTENT_TYPE;
+
use atuin_common::api::*;
pub fn verify_str(secret: &str, verify: &str) -> bool {
@@ -32,6 +36,30 @@ pub fn verify_str(secret: &str, verify: &str) -> bool {
}
}
+// Try to send a Discord webhook once - if it fails, we don't retry. "At most once", and best effort.
+// Don't return the status because if this fails, we don't really care.
+async fn send_register_hook(url: &str, username: String, registered: String) {
+ let hook = HashMap::from([
+ ("username", username),
+ ("content", format!("{registered} has just signed up!")),
+ ]);
+
+ let client = reqwest::Client::new();
+
+ let resp = client
+ .post(url)
+ .timeout(Duration::new(5, 0))
+ .header(CONTENT_TYPE, "application/json")
+ .json(&hook)
+ .send()
+ .await;
+
+ match resp {
+ Ok(_) => info!("register webhook sent ok!"),
+ Err(e) => error!("failed to send register webhook: {}", e),
+ }
+}
+
#[instrument(skip_all, fields(user.username = username.as_str()))]
pub async fn get<DB: Database>(
Path(username): Path<String>,
@@ -71,8 +99,8 @@ pub async fn register<DB: Database>(
let hashed = hash_secret(&register.password);
let new_user = NewUser {
- email: register.email,
- username: register.username,
+ email: register.email.clone(),
+ username: register.username.clone(),
password: hashed,
};
@@ -94,6 +122,16 @@ pub async fn register<DB: Database>(
token: (&token).into(),
};
+ if let Some(url) = &state.settings.register_webhook_url {
+ // Could probs be run on another thread, but it's ok atm
+ send_register_hook(
+ url,
+ state.settings.register_webhook_username.clone(),
+ register.username,
+ )
+ .await;
+ }
+
match db.add_session(&new_session).await {
Ok(_) => Ok(Json(RegisterResponse { session: token })),
Err(e) => {